数据库事务浅析

数据库为什么要有事务,因为,事务是数据库区别于文件系统的特性之一。在文件系统中,如果你正在对2个文件进行修改,一个更新成功,另外一个在更新之前系统崩溃了,那么这就会有2个不同步的文件。

数据库中事务的基本作用就是将数据库从一种一致性状态转变为另外一种一致性状态。

数据库事务有4个特征(acid):
1.原子性(atomicity):事务中的所有动作要么都发生,要么都不发生。
2.一致性(consistency):事务将数据库状态从一种一致状态转变为下一种一致状态。
3.隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。
4.持久性(durability):事务一旦提交,其结果就永久性的。

ANSI/ISO SQL标准定义了4种事务隔离级别,对于相同的事务,采用不同的隔离级别有不同的结果。隔离级别是通过3种现象来定义的,3种现象可能允许或者可能不允许来定义隔离级别。

脏读(dirty read):无效数据的读出。简言之就是你读取到了别人未提交的数据。脏读就是指当一个事务T1正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,(因为事务还没有提交,所以还没有持久化到数据库),这时,另外一个事务T2也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

不可重复度(nonrepeatable read):也就是说,如果你在T1时间读取某一行,在T2时间重新读取这一行时,这一行可能有所修改。也许它已经消失,也可能被更新了,等等。

幻像读(phantom read):这说明,如果你在T1时间执行一个查询,而在T2时间再次执行这个查询,此时可能已经向数据库里添加了另外的行,这会影响你的结果,与不可重复读的区别在于:在幻像读中,已经查询的数据不会改变,只是与以前相比,会有更多的数据满足你的查询条件。

SQL的隔离级别是根据以下原则定义的,即是否允许上述的各个现象。

隔离级别 脏读 不可重复读 幻像读
read uncommitted 允许 允许 允许
read committed 允许 允许
repeatable read 允许
serializable 允许

在spring中,事务还有以下传播级别:

propagation_mandatory:要求调用该方法的线程必须处于事务环境中,否则抛出异常。
propagation_nested:如果执行该方法的的线程已经处于事务环境下,依然启动新的事务,方法在嵌套的事务里执行。如果执行该方法的线程未在事务中,也启动新的事务,然后执行该方法。
propagation_never:不允许调用该方法的线程处于事务环境下,如果调用该方法的线程处于事务环境下,则抛异常。
propagation_not_supported:如果调用该方法的线程处于事务中,则先暂停当前事务,然后执行该方法。
propagation_required:要求在事务中执行该方法,如果当前线程已经处于事务中,则直接调用,如果当前线程不处于事务中,则启动新的事务后执行该方法。(默认)
propagation_requires_new:该方法要求在新的事务中执行,如果当前线程已经处于事务中,则先暂停当前事务,启动新事务后执行该方法,如果当前调用线程不处于事务中,则启动新的事务后执行方法。
propagation_supports:如果当前执行线程处于事务环境中,则使用当前事务,否则不适用事务。

此条目发表在数据库分类目录,贴了标签。将固定链接加入收藏夹。