如何防止在UPDATE并发问题通过iBatis的(How to prevent concurrenc

2019-08-01 00:08发布

我们的Java EE Web应用程序进行使用iBATIS(ORM)的数据库操作。 数据库的操作流程为下面

流量 :JSP --->动作---> ServiceIMpl ---> DaoImpl ---->调用更新查询直通”的iBatis

:操作,服务和DAO类是使用Spring 2.5的依赖注入技术实例化。 我们使用Struts2的。

问题 :2个并发用户搜索相同的记录和用户1更新ATTRIBUTE1而用户2更新Attribute2。 在“保存” user1的第一次点击,然后用户2点击Save(他们遵循彼此的几秒钟的差别)。 当我们看到在数据库中的数据,只有用户1的更新存在。 审计列也只显示用户1的更新。 用户2对Attribute2更新不这样做,在Sametime中没有异常抛出。

我们尝试使用开始交易,并在iBatis的提交事务周围的SqlMap的XML定义更新询问的invokation。 同样的问题仍然存在。 我们也试图消除这些交易的命令,但问题仍然存在。

我们应该做什么特别的事情/不同的更新过程中处理并发? 不会像奥姆斯iBatis的手柄本身?

附加信息 :进一步的调查显示以下信息。

当用户1和用户2点击的记录,它的完整的数据被取出观看。

现在,当用户1都与用户2改变一些属性,然后单击Save(兼),先说User1的数据进行更新,然后同时用户2的数据正在更新,用户1的已更新的数据是在写和丢失。

What approach is usually followed in such screens to handle such scenarios ?

Answer 1:

你的问题不在于交易,这是你的东西修改之前,你必须确保上次阅读它,没有人修改。

在Web应用程序,你应该使用乐观锁 。 基本上,你在你的表中,有在初始值的“版本”字段中insert (tipically 1),并得到每个增量update 。 步骤如下:

  1. 从表中读取数据, 包括版本字段

  2. 发送数据的客户端,包括版本字段

  3. 从客户端接收修改的数据,包括版本字段不变

  4. 更新表和增量的版本但前提是该行的版本字段是一样的从客户端接收到的原始之一 。 也就是说,当你有

     update ... where id = :id_from_client 

    现在你应该做的

     update ..., version = version + 1 where id = :id_from_client and version = :version_from_client 
  5. 获取更新的行数(通常可以马上从你的持久化框架的更新操作这些信息)。 如果有更新的行数为1,操作succeded。 如果有更新的行数为0,则应该发出信号并发错误。

一个例子:

  1. 用户1获取数据,与版本= 17

  2. 用户2得到的数据,与版本= 17

  3. 用户1原子(原子来源于作为一个单独的SQL语句):

    • 检查版本= 17
    • 更新数据
    • 设置版本18

  4. 用户2原子:

    • 检查版本= 17
    • 由于版本是真的18,信号并发错误并中止操作,通知该操作无法完成用户由于其他人修改相同的数据。

目前大多数持久性框架为这个开箱即用支持的,大多自动(见JPA @Version注释 ,例如)。 iBatis的似乎没有它,但因为它是非常接近SQL,你不应该有很多问题自己实现它。 看到这个博客条目约乐观锁定iBatis的一些细节 。

有了这个计划,你就不会迷路更新,唯一的问题是,一些特定情况下会惹恼用户很多:想象你花上5分钟时间填写一些表格只在最后被告知您的操作无法完成,你需要从一开始就重试! 在这些少数情况下,你应该实现的东西对乐观锁定的顶部更复杂。 我会用某种形式的远程资源租赁 (链接?)的:

  1. 客户端请求数据到服务器租赁

  2. 如果数据已经租赁给其他客户端,信号并发错误。

  3. 否则授予租赁客户端的时间有限

  4. 租赁期满之前,服务器授予数据的客户端独占访问。 客户端还可以请求租用更新(经由AJAX,例如)。 服务器可以接受或拒绝更新。 (租赁时间和更新政策应该取决于被处理的具体使用情况下,服务器决定)。

  5. 租约到期(这可以用在服务器计划的任务来完成,例如)。 当租约到期时,数据应被视为“解锁”,除非客户端被授予新租约的服务器应该拒绝访问的客户端。

通过这种方式,用户可以得知有人正在修改相同的数据,他们甚至开始任何冗长的操作,他们试图完成之前



Answer 2:

ibatis的不执行锁定.Seeing你的情况乐观锁可以解决problem.To实现乐观锁,你可以有选择。 1.使用框架的事务管理,像org.springframework.jdbc.datasource支持 DataSourceTransactionManager对象 。他们提供传播行为和隔离level.But,您使用的必须支持传播水平和隔离level.Spring提供以下隔离级别的数据源。 .ISOLATION_DEFAULT .ISOLATION_READ_UNCOMMITTED .ISOLATION_READ_COMMITTED .ISOLATION_REPEATABLE_READ .ISOLATION_SERIALIZABLE。 2.Next你可以提供你的执行乐观锁定的。



文章来源: How to prevent concurrency issue in UPDATE via iBatis