您的位置:首页 > 其它

乐观锁

2015-06-21 17:01 295 查看
1.使用原因

实际上是为了解决数据库并发访问的情况。

如一个银行账户中余额为1000元,A向其中转账200,B从中取出300,那么应该是剩余900,。

但实际情况下,可能是A转了200,但是还没有提交事务,这个时候B获取余额信息,值是1000,取出300后,修改余额为700,提交事务,然后A又提交事务,这时候账户余额变为1200,显然是不对的。

这个时候就需要一种机制来保证,同一时间只有一个事务能操作这条数据,这个时候就可以使用乐观锁

2.实现

(1)使用version字段

在数据库表中添加一个数字类型的version字段。当读取数据库时,讲version字段的值一起读出,数据每更新一次,对此version+1.当我们提交更新的时候,判断数据库表中记录的version字段与之前读出的version的值是否相同,如果相同,就说明期间没有被其他事务修改,可以更新;如果不相同,说明已经是过期数据了,不能更新



(2)使用更新时间

在数据库表中定义一个更新时间,也是在提交的时候比较当前数据库中的数据的时间和自己取到的时间是否相同,如果一致则可以更新,否则就是版本冲突

3.实例

(1)数据库表



(2)数据库操作(此处ibatis+spring实现)

public Integer updatePersonCAS(Person person)
{
return getSqlMapClientTemplate().update("person.updatePersonCAS", person);
}
sql

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="person">
<!-- 使用别名可以避免每次都输入类路径全称 -->
<typeAlias alias="Person" type="com.mycompany.app.dataObject.Person"/>

<resultMap id="PersonResult" class="Person" >
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="version" column="version"/>
</resultMap>

<update id="updatePersonCAS" parameterClass="Person" >
update person set name=#name# ,version=version+1
where id=#id# and version=#version#
</update>

<!-- 根据id查询用户信息 -->
<select id="selectPersonById" parameterClass="java.lang.Integer" resultClass="Person">
SELECT * FROM person WHERE ID=#id#
</select>

<sqlMap>


(3)测试

@Test
public void testUpdatePersonCAS()
{
Person person = personDAO.selectById(1);
person.setName("cas");
Integer res = personDAO.updatePersonCAS(person);
if (res!=1) {
System.out.println("has been modified!");
}
else {
System.out.println("modified success!");
}

person.setName("cas2");
Integer res2 = personDAO.updatePersonCAS(person);
if (res2!=1) {
System.out.println("has been modified!");
}
else {
System.out.println("modified success!");
}
}
结果为:

modified success!

has been modified!

4.注意

使用乐观锁的时候,是否记录已经被更改是通过update的返回值来确定的!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: