月度归档:2013 年十月

数据库事务的几个概念

1,第一类丢失更新;2,脏读;3,虚读;4,不可重复读;5,第二类丢失更新;

1、第一类丢失更新(lost update):

事务1、2同时开启,同时读取数据,事务2修改数据后先提交,然后事物1修改数据后回滚。结果事务1回滚了事务2的操作,导致事务2的修改操作丢失。

2,脏读(dirty   reads):

事务1先开启事务读取了数据,然后进行了修改未提交。此时事务2开启,读取了事务1未提交的数据,此时事务1回滚,然后事务2提交。结果事务2的提交把事务1回滚的操作丢失了。

3,虚读(幻读)(phantom   reads):

事务1开启读取了数据未提交。此时事务2开启,并进行了数据插入或者删除操作,然后提交。此时事务2再次读取数据,发现与先前的数据不一致

4、不可重复读( non-repeatable   reads):

事务1开启读取了数据未提交,然后事务2开启并对事务1读取的数据进行了修改(不知道删除算不算),然后事务2提交。此时事务1再次读取数据时发现与开始读取的数据不一致。

*这里不可重复读与虚读有点混乱,我个人感觉虚读是读取的结果是一个结果集可能是很多条的记录,第二次读取时候结果集的数据增加了一些新的内容或者比第一次读取的数据少了,因为被另外一个事务做了插入新数据或者删除了老数据操作;而不可重复读则是读取到了某一条记录,第二次读取的与第一次读取的数据内容不一致,因为被另外一个事务修改了。两者的侧重点不同,虚读侧重表,而不可重复读侧重行;虚读侧重添加或删除,不可重复读侧重修改。

不可重复读和脏读也有些相似之处,都是读取到了另外一个事务修改的数据,但是不可重复读是读取两次,第二次读取到的是另外一个事务已经提交了的,而脏读确实读取到另外一个事务未提交前的数据,且把另外一个已提交的事务给覆盖了造成数据有丢失。

5,第二类丢失更新:

在不可重复读中,事务1的第二次读取未发生,而是直接或者做了其他修改操作提交了,导致事务2的修改操作丢失了,数据回到开始前的数据。

个人感觉与第一类的区别为一个是修改回滚,一个是又或者没有修改然后提交。

举例:

对于同一个银行帐户A内有200元,甲进行提款操作100元,乙进行转帐操作100元到B帐户。如果事务没有进行隔离可能会并发如下问题:
1、第一类丢失更新:首先甲提款时帐户内有200元,同时乙转帐也是200元,然后甲乙同时操作,甲操作成功取走100元,乙操作失败回滚,帐户内最终为200元,这样甲的操作被覆盖掉了,银行损失100元。
2、脏读:甲取款100元未提交,乙进行转帐查到帐户内剩有100元,这是甲放弃操作回滚,乙正常操作提交,帐户内最终为0元,乙读取了甲的脏数据,客户损失100元。
3、虚读:和脏读类似,是针对于插入操作过程中的读取问题,如丙存款100元未提交,这时银行做报表进行统计查询帐户为200元,然后丙提交了,这时银行再统计发现帐户为300元了,无法判断到底以哪个为准?
大家好像觉得统计这个东西肯定是时时更新的,这种情况很正常;但是如果统计是在一个事务中的时候就不正常了,比如我们的一个统计应用需要将统计结果分别输出到电脑屏幕和远程网络某台计算机的磁盘文件中,为了
提高性能和用户响应我们分成2个线程,这时先完成的和后完成的统计数据就可能不一致,我们就不知道以哪个为准了。
4、不可重复读:甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,这时乙在准备最后更新的时候又进行了一次查询,发现结果是100元,这时乙就会很困惑,不知道该将帐户改为100还是0。
和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
5、第二类丢失更新:是不可重复读的一种特例,如上,乙不做第二次查询而是直接操作完成,帐户内最终为200元;或者是乙存了100元提交,最终账户内为300元。甲的操作被覆盖掉了,银行损失100元。

锁:

x锁(eXclusive lock) 排他锁/写锁: 被加锁的对象只能被持有锁的事务读取和修改,其他事务无法在该对象上加其他锁,也不能读取和修改该对象

s锁(Share lock) 共享锁/读锁: 被加锁的对象可以被持锁事务读取,但是不能被修改,其他事务也可以在上面再加s锁。

(U) 锁 更新锁:可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。

封锁协议:
一级封锁协议:
在事务修改数据的时候加x锁,直到事务结束(提交或者回滚)释放x锁。一级封锁协议可以有效的防止丢失更新,但是不能防止脏读不可重复读的出现。
二级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,读取之后释放。二级封锁协议可以防止丢失更新,脏读。不能防止不可重复读。
三级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,直到事务结束释放。二级封锁协议可以防止丢失更新,脏读,不可重复读。

参考:多角度彻底理解数据库事务中的”脏读”.”不可重复的读”及”虚读”

Hibernate事务与并发问题处理(乐观锁与悲观锁)

java浏览器插件-applet(二)

接上一篇文章

如果调用

Runtime.getRuntime().exec(cmd)

或者调用本地动态链接库native方法,applet就不能正常工作了。因为applet要做这些操作需要更高的权限。

提升权限解决办法有两个:

方法一、AccessController类

调用AccessController的doPrivileged方法提升权限,参数为PrivilegedAction实例对象,代码如下:

AccessController.doPrivileged(new PrivilegedAction<String>() {
  public String run() {
    String res;
    //your code
    return res;
  }
});

在yourcode中就可以调用本地方法,或者访问本地其他文件或者操作了;res为操作后的返回值。

方法二:导入证书(未做测试)

在上一篇文章中有提到导出证书,导出的证书名字为scancard.cert,导出证书后,将证书再导入到用户的系统中:

keytool -import -alias scancard -file scancard.cert

这样我个人觉得麻烦,增加了用户的工作,也未做测试。

applet访问javascript:

这里需要用到一个类:netscape.javascript.JSObject。需要导入plugin.jar的jar包,jar包所在位置在jre的lib目录下。

代码如下:

JSObject jo = JSObject.getWindow(this);

Object obj = jo.eval("jsFn('hello word')");

其中this只想当前的applet对象,jsFn为applet所在的页面的javascript方法。obj为jsFn的返回值。

javascript访问applet方法、属性:

上一篇中讲到了<applet>标签和<jsp:plugin >标签有个name属性,这个name属性就是这个applet实例在javascript中的引用了。假设name属性为‘scanCardPlugin’,applet中有个方法为:

public String scan(String arg){}

则javascript代码如下:

var res = document.scanCardPlugin.scan();

如此便可以访问到scan方法了,res为scan的返回值。ps: applet被js访问的方法必须是public的。

以上有个浏览器兼容的问题:在ie下<applet>和<jsp:plugin>都没问题;

但是在chrom下<jsp:plugin>的那么对象能访问到,而对象的方法或者对象却不能正确访问,document.scanCardPlugin.scan返回undefined,

解决方法:同时使用两个标签,即<applet>和<jsp:plugin>都写上去,但是name属性写两个不同的,如:

<!--其他属性略-->

<jsp:plugin name="scanCardPlugin" ></jsp:plugin>

<applet name="scanCardPlugin2" ></applet>

javascript代码如下:

var res;
try{
res = document.scanCardPlugin.scan();
}catch(e){
res = document.scanCardPlugin2.scan();
}

//如果是访问属性那就简单了

res = document.scanCardPlugin.param || document.scanCardPlugin2.param;

java浏览器插件-applet

这两天项目中需要在浏览器中调用本地设备,研究了下java的applet,把学习笔记在此分享。

一,

首先需要建立一个继承import javax.swing.JApplet的类;

JApplet两个我比较关心的方法:

public void init()

:初始化applet时候会调用此方法,在生命周期中只调用一次,一般界面初始化代码写在这里,或者写在构造器方法中

public void destory()

:销毁方法,同样在生命周期中只调用多次。

另外还有 start() ,stop() 方法,可在生命周期中调用多次。

浏览器操作中方法调用顺序:

浏览器加载Applet:init–>start

浏览器刷新: stop–>destory–>init–>start

浏览器推出:stop–>destory

二,

applet写完后,就是用eclipse或者jar命令打包了,

打包后运行一些基本逻辑就没问题了。

但是如果要访问本地文件之类的操作可能就没这个权限了,解决办法是给jar包数字签名:

1,生成store证书文件scancard.store,scancard为自己指定的名字 :

keytool -genkey -keystore scancard.store -alias scancard

提示输入密码,记住自己输入的密码,下一步需要,其他的组织名,公司名等任意填写或一路回车 2,给jar包签名:

jarsigner -keystore scancard.store ScanCard.jar scancard

scancard.store为刚才生成的store, ScanCard.jar为刚才的jar包 ,最后的scancard貌似任意填写都可以 这样你的jar包权限就提升了,放在浏览器中就能做进一步的操作了 运行这个命令后如果你发现提示你证书6个月过期,可以在第一个命令后面加上如下参数指定有效期,单位(天),这里指定有效期为10年:-validity 3650
*这里好像还可以将证书导入,用于浏览器的某些认证,目前还没用到:

keytool -export -keystore scancard.store -alias scancard -file scancard.cert

三,

将jar包嵌入到html中:

两种方式:

1,jsp实现,

<jsp:plugin codebase="." archive="ScanCard.jar"
 code="com.cloudview.ScanCard.class" name="scanCardPlugin" width="0"
 height="0" type="applet">
 <jsp:fallback>您的浏览器不支持JAVA Applet,请更换浏览器,推荐用Chrome或Firefox</jsp:fallback>
 </jsp:plugin>

codebase为一般配置为”.”,表示jar包为当前路径

archive为嵌入的jar包

code为需要调用的applet class,貌似可以不写”.class”

name为自己指定的一个标志,可以任意写,这个为js调用提供的,后续会讲到,

*这里还能给applet传递参数,在jsp:plugin内加入如下代码:

<jsp:param name="param1" value="<%=#request.getAttribute("param1")%>" />

在applet类 init() 方法中接收方法:

String param1 = getParameter("param1");

2,html实现,

<applet codebase="." archive="ScanCard.jar" code="com.cloudview.ScanCard.class" name="scanCardPlugin2" width="0" height="0">
</applet>

这种貌似浏览器兼容性没有第一种好,但是,这种方法在有的浏览器中某些功能兼容性又更好。

参数同第一种

另外,javascript和applet可以互相访问,applet权限还可以进一步提高到操作调用本地设备,运行Runtime的exec方法以调用浏览器端的dos命令或shell命令,未完待续。。。见:下一篇

参考:http://www.cnblogs.com/ziziwu/archive/2012/03/21/2410159.html

wordpress学习笔记-模版01

模版建立:主题目录下(wp-content/themes/theme01/)新建一个php文件如:example.php
需修改权限为可写

列出最近12个月的归档文章(显示的是月份列表,如:2013 年十二月):

<!--?php wp_get_archives('type=<strong-->monthly&limit=12'); ?>

列出最近30天的文章(显示的是文章发表的日期列表,如:2013 年 12 月 11 日):

</pre>
<pre title=""><!--?php wp_get_archives('type=daily&limit=30'); ?-->

列出最近发表的20篇文章,我个人比较喜欢,是显示标题列表,如:标题1

<!--?php wp_get_archives('type=<strong-->postbypost&limit=20&format=custom'); ?>

用下拉列表框显示每个月的月度文章,并显示当月文章总数目,如:2013 年十二月  (1) :

<select name="archive-dropdown" onChange='document.location.href=this.options[this.selectedIndex].value;'>
<option value=""><?php echo attribute_escape(__('Select Month')); ?></option>
<?php wp_get_archives('type=monthly&format=option&show_post_count=1'); ?> </select>

按字母/汉字排序列出已发表的所有文章:

<!--?php wp_get_archives('type=<strong-->alpha'); ?>

参考: wp_get_archives的官方文档; http://farlee.info/archives/wordpress-all-archives-index-page.html