Java事务小结
来源:互联网 发布:知乎折叠 编辑:程序博客网 时间:2024/05/17 04:19
1.事务的简单理解
一组由多个操作形成的工作单元,该工作单元的所有操作要么全部执行,要么全部取消.
在对数据库进行操纵时候需要考虑事务,事务一般交给应用程序来设置,最终在数据库端执行.
所以一般要求数据库服务器支持事务处理.
2.事务类型
在java中一般分为两种:全局事务,本地事务
全局事务采用JTA控制,可以控制多个数据源.
本地事务即JDBC事务,由Connection控制,不能跨数据源.
java.sql.Connection 提供了以下控制事务的方法:
3.事务以及Spring事务管理
J2ee开发中常用Spring来控制事务. 一般采用声明式事务管理器,基于Aop实现
3.1 事务的四个特性(ACDI)
Atomic(原子性)
一个事务被看成一个工作单元,要么全部成功,要么全部失败.
Consistency(一致性)
要求事务必须确保数据库的状态保持一致,这就是说事务开始时,数据库的状态是一致的;在事务结束时,数据库的状态也必须是一致的
Isolation(隔离性)
要求系统必须保证事务不受其他并发执行的事务的影响.
Durability(持久性)
事务一旦成功,在系统中的变化时持久的.
3.2 事务的传播属性
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。
如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)
常见情形一:
当程序调用ServiceA.methodA()前Spring容器会根据事物的传播属性来判断是否需要开启事务
比如目前是PROPAGATION_REQUIRED(假设目前没有事务),则调用ServiceA.methodA()前Spring会开启一个事务.
常见情形二:
Spring容器会根据ServiceA的事物传播属性PROPAGATION_REQUIRED(假设目前没有事务)在调用ServiceA.methodA()前开启一个事务,当执行到ServiceB.methodB(),因为目前已经在一个事务中,ServiceB的事物传播属性为PROPAGATION_REQUIRED,所以spring不会再开启事务.
什么时候会新起一个事务呢?当ServiceB的事务传播属性设为为PROPAGATION_REQUIRES_NEW,spring会把当前事务挂起,重新开启新的事务.
3.3 事务的隔离级别以及并发控制(来自网上)
事务隔离级别属于处理多事务并发的问题
1 Serializable:最严格的级别,事务串行执行,资源消耗最大;
2 REPEATABLE READ:读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3 READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4 Read Uncommitted:最低的事务隔离级别,保证了读取过程中不会读取到非法数据。
并行可以提高数据库的吞吐量和效率,但是并不是所有的并发事务都可以并发运行,这需要查看数据库教材的可串行化条件判断
并发中可能发生的3种情况
1 Dirty reads(脏读):一个事务读取了另一个未提交的并行事务写的数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
2 non-repeatable reads(不可重复读,同一事务多次读取不一致):一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务修改过。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。
3 phantom reads(幻读):一个事务重新执行一个查询,返回一套符合查询条件的行,发现这些行因为其他最近提交的事务而发生了改变。这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
隔离级别总结:
Serializable 不会 不会 不会
REPEATABLE READ 不会 不会 会
READ COMMITTED 不会 会 会
Read Uncommitted 会 会 会
常见的并发控制策略(from:深入浅出hibernate)
1.悲观锁
悲观锁大多情况利用数据库的锁机制实现(利用for update子句),以保证操作操作最大程度的独占性,随之而来的是数据库性能的大开销,特别是对长事务而言,这样开销无法承受.
ex.select * from account where name = "Erica" for update
这条Sql锁定了account表中所有符合检索条件(name="Erica")的记录.本次事务提交前(事务提交时会释放过程中的锁),外界无法修改这些记录.
2.乐观锁
大多基于数据版本(Version)记录机制实现.既在数据库表中增加一个"version"字段来实现.
读取数据时,将此版本号一同读出,之后更新,将此版本号加1.此时,将提交的数据的版本数据与数据库对应记录的当前版本信息比较,如果提交的数据版本号大于数据当前版本号, 则给予更新,否则认为是过期数据.
2.http://msdn.microsoft.com/zh-cn/library/ms189122.aspx
3.http://yuquan-nana.javaeye.com/blog/295639
- Java事务小结
- java 事务小结
- JAVA分布式事务小结
- 事务小结
- 事务小结
- 事务小结
- 事务属性小结
- 事务属性小结
- 数据库操作事务小结
- 事务属性小结
- transaction事务小结
- Spring--事务小结
- 事务---Java事务
- Java事务--JDBC事务
- ADO.NET事务学习小结
- spring中事务的小结
- 事务型数据库设计小结
- 一个XA事务问题解决小结
- VB连接SAP实例
- JavaScript 变量作用域及闭包
- 操作系统——动态优先级调度算法源代码
- Nutch 的集群式搜索引擎
- 设备日志信息采集方案
- Java事务小结
- c语言中浮点数的表示形式
- js正确获取元素样式详解
- Asp.net弹出层并且有遮罩层
- 电子书下载
- js进度条
- js进度条(简单的)
- 公信力不能在29秒中发烧死亡
- 正则表达式 一看就会