使用自动提交并不意味着事务不再用于访问数据。它只是意味着每个语句现在都在它自己的事务中执行。在JDBC规范中定义事务开始和终止时的确切实例。为了简洁起见,这通常取决于所执行的声明的性质。
我不确定您的设计是如何实现的,但非事务性系统通常会遇到三个问题。自动提交的使用可能会重新引入一个或多个这些问题。
脏读
考虑您的应用程序中的线程A将读取的实体和更新,但没有提交新的价值。考虑另一个读取同一个实体并看到更新值的线程B.如果线程A要回滚它的更改,或者未能提交更新的值,那么B基本上使用脏值,因为它执行了脏读。
它自己的自动提交不会导致脏读。但是,如果您有一系列最初在单个事务中执行的数据库读写操作,在每次读取/写入操作之后使序列提交,将导致其他事务中的脏读操作,因为当前事务可能会简单地回滚改变。
非可重复读取
在事务的上下文中,读出同一实体(记录)两次在事务的范围内,并看到在第二读取不同的值被认为是一种非可重复阅读。当不同的事务提交了更改并且正在进行的事务读取新值时会发生这种情况。
使用自动提交(或者更确切地说是在两个不同的事务中执行读操作)很可能会导致不可重复的读操作,因为同一个线程中的读操作都将在不同的事务上下文中执行,导致第二次读取看到提交的值(来自不同线程中的事务)。
幻像读
非常相似,不可重复的读取,但并不完全。在这种情况下,执行第二次读取的执行线程将以新记录的形式看到更多数据(而不是更新的数据)。
同样,由于相同的原因,使用自动提交很可能会导致应用程序中的幻像读取。
这些问题还将取决于所使用的数据库事务隔离级别,但最终在使用ORM框架时,标记事务的开始和结束将留给应用程序开发人员。虽然单个读写操作可能会被数据库彼此隔离,但开发人员需要确保工作在事务环境中进行。使用自动提交会更改每个操作的事务上下文。
TLDR
使用自动提交时进行交易活动将意味着这是不可能的“业务事务上下文”期间执行回滚到安全状态,在发生故障的事件。另外,正是由于这个原因,在JDBC中执行批量更新时,应该禁用自动提交。当真正的需求是在批处理结束时提交时,使用自动提交将强制为批处理中的每个更新执行提交。
我建议您阅读本书Java Transaction Design Strategies(以免费电子书形式提供),以深入了解使用交易。
打开自动提交并不意味着您不再使用事务。每条语句都会在它自己的事务中运行。 – 2011-06-13 19:40:22
@Vineet也许我可以更好地改写它。我的意思是代码的其他部分应该使用事务来获取数据(beginTransaction(),获取或设置数据,commit()),而不是pojo本身。 – TheLQ 2011-06-13 19:42:51
那么,如果其他部分正在执行数据访问,那么POJO会做什么呢?通过推论,为什么POJO现在应该担心自动提交? – 2011-06-13 19:46:48