JavaEE事务

一、什么是事务?

事务(Transaction)是作为单个逻辑工作单元执行的一系列操作。这些操作作为一个整体向系统提交,要么都执行、要么都不执行。事务是一个不可分割的工作逻辑单元

转账操作A—>B:

begin transaction

1.更新帐户A的余额

2.记录帐户A的交易日志

3.更新帐户B的余额

4.记录帐户B的交易日志

end transaction

二、事务的特征(ACID)

原子性Atomicity

事务必须是原子工作单元。对于其数据修改,要么全执行,要么全都不执行。

一致性Consistency

事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构都必须是正确的。在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

隔离性Isolation

由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

持久性Durability

事务完成之后,它对于系统的影响是永久性的: 该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

三、事务管理策略

容器管理事务(CMT  Container Manage Transaction)

Bean管理事务(BMT Bean Manage Transaction )

JTA: Java Transaction API

1.JTA是JavaEE提供的管理分布式事务的一系列接口,它提供了TransactionManager和ResourceManager之间沟通机制。

a.javax.transaction.UserTransaction提供给应用程序代码直接使用的接口,用于定义事务边界和获取事务状态。

b.javax.transaction.TransactionManager主要由应用服务器使用的接口,除了定义事务边界和获取事务状态,还可以挂起(suspend)或者重启(resume)事务。

四、事务属性

Required:

方法调用要求事务上下文,如果已经存在一个事务上下文,那么就是用这个,如果不存在,则创建一个新的如果不存在新事务,容器启动新的事务,如果存在事务,bean使用该事务。

RequiresNew:

容器在bean上的每个方法调用之前创建新事务,并在返回之前提交事务。调用bean方法的时候,总是启动新事务。如果事务已经存在,则悬挂该事务,直到新事务完成。

NotSupported:

bean运行在事务上下文的外部。在方法调用期间,悬挂起了现有事务。不能在事务内部调用bean。悬挂现有的事务,直到该bean中调用的方法完成。

Supports:

如果存在事务上下文,方法调用使用当前事务上下文。如果不存在,则不创建新的事务上下文。容器不启动新的事务。如果事务已存在,bean将包含在这个事务中。

注意:使用这个属性,没有事务,bean也能运行。

Mandatory:

方法调用需要事务上下文。如果不存在,抛出异常。必须已经存在活动事务。如果不存在事务,则抛出javax.ejb.TransactionRequiredException。

Never:

方法调用要求不存在事务上下文。如果存在,则抛出异常。bean必须永远不同事务同时运行。如果存在事务,则抛出java.rmi.RemoteException。

事务属性-事务传播

五、事务隔离级别

目的:在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。

问题:

更新丢失(Lost update)

两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。

脏读(Dirty Reads)

一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。

不可重复读(Non-repeatable Reads)

一个事务对同一行数据重复读取两次,但是却得到了不同的结果。它包括以下情况:

(1) 事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。

(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。

未授权读取ISOLATION_READ_UNCOMMITED

允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。

授权读取ISOLATION_READ_COMMITTED

允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

可重复读取ISOLATION_REPEATABLE_READ

禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

序列化ISOLATION_SERIALIZABLE

这个常量表示脏读取,非重复读取和不真实读取都被禁止。

这个级别包括在TRANSACTION_REPEATABLE_READ阻止的事情,以及防止一个事务在满足WHERE条件下读所有的行记录,第二个事务在满足WHERE条件下插入一行,随后前一个事务在同样的条件下重复读取,这是获得的是不真实的行记录。

ISOLATION_DEFAULT(Spring)

默认隔离级别是与具体的数据库相关的,采取的是具体数据库的默认隔离级别,不同的数据库是不一样的

事务隔离策略

Weblogic:

weblogic-ejb-jar.xml

<transaction-isolation>

<isolation-level>TransactionSerializable</isolation-level>

<method>

<ejb-name>TradingService</ejb-name>

<method-inf>Remote</method-inf>

<method-name>placeTrade</method-name>

</method>

</transaction-isolation>

Spring:

<bean id=“tradingService" class=“org.springframework.transaction.interceptor. TransactionProxyFactoryBean">

<property name="transactionManager"><ref bean="transactionManager"/></property>

<property name="target"><ref local=" tradingService Target"/></property>

<property name="transactionAttributes">

<props>

<prop key=“insert*">PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE</prop>

</props>

</property>

</bean>

六、事务类型

本地事务模型:Local Transaction Model

程序定制事务模型:Programmatic Transaction Model

申明式事务模型:Declarative Transaction Model

七、分布式事务

多个数据源

两段提交协议

第一步,事务控制器询问各资源管理器是否准备好提交;

第二步,如果所有资源管理器都准备好提交,则事务管理器要求所有进行提交。

Spring事务处理

1.声明式事务管理

2.编程式事务管理

Spring声明式事务不提供高端应用服务器提供的跨越远程调用的事务上下文传播。如果你需要这些特性,我们推荐你使用EJB。 然而,不要轻易使用这些特性。因为通常我们并不希望事务跨越远程调用。

Spring中事务处理-申明式事务管理

事务属性

PROPAGATION_REQUIRED

PROPAGATION_SUPPORTS

PROPAGATION_MANDATORY

PROPAGATION_REQUIRES_NEW

PROPAGATION_NOT_SUPPORTED

PROPAGATION_NEVER

PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚

Isolation隔离级别

read-only是否只读,默认为false

大多数Spring用户选择声明式事务管理。这是对应用代码影响最小的选择,因此也最符合 非侵入式 轻量级容器的理念。

java

// the service class that we want to make transactional

@Transactional

public class DefaultFooService implements FooService {

Foo getFoo(String fooName);

Foo getFoo(String fooName, String barName);

void insertFoo(Foo foo);

void updateFoo(Foo foo);

}

xml

<tx:annotation-driven transaction-manager="txManager"/>

<!-- a PlatformTransactionManager is still required -->

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<!-- (this dependency is defined somewhere else) -->

<property name="dataSource" ref="dataSource"/>

</bean>

Spring中事务处理-编程式事务管理

使用 TransactionTemplate (推荐)

直接使用一个 PlatformTransactionManager 实现

使用 TransactionTemplate

private final TransactionTemplate transactionTemplate;

// use constructor-injection to supply the PlatformTransactionManager

public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The ‘transactionManager‘ argument must not be null.");

this.transactionTemplate = new TransactionTemplate(transactionManager);

// the transaction settings can be set here explicitly if so desired this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED); //设定事务隔离级别

this.transactionTemplate.setTimeout(30); // 事务超时

}

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

protected void doInTransactionWithoutResult(TransactionStatus status) {

try {

updateOperation1();

updateOperation2();

} catch (SomeBusinessExeption ex) {

status.setRollbackOnly(); //回滚

}

}

});

使用 PlatformTransactionManager

DefaultTransactionDefinition def = new DefaultTransactionDefinition();

// explicitly setting the transaction name is something that can only be done programmatically

def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = txManager.getTransaction(def);

try {

// execute your business logic here

} catch (MyException ex) {

txManager.rollback(status);

throw ex;

}

txManager.commit(status);

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>

时间: 2024-08-27 17:47:57

JavaEE事务的相关文章

Spring 事务相关点整理

Spring和事务的关系 关系型数据库.某些消息队列等产品或中间件称为事务性资源,因为它们本身支持事务,也能够处理事务. Spring很显然不是事务性资源,但是它可以管理事务性资源,所以Spring和事务之间是管理关系. 就像起码很多领导虽然不会写代码,但是他却管理着一大批会写代码的码农. Spring事务三要素 数据源:表示具体的事务性资源,是事务的真正处理者,如MySQL等. 事务管理器:像一个大管家,从整体上管理事务的处理过程,如打开.提交.回滚等. 事务应用和属性配置:像一个标识符,表明

[JavaEE - JPA] 3. Spring Framework中的事务管理

前文讨论了事务划分(Transaction Demarcation)在EJB中是如何实现的,本文继续介绍在Spring Framework中是如何完成事务划分的. 我们已经知道了当采用Container事务类型的时候,事务划分主要有以下两种方案(参考这里): 使用JTA接口在应用中编码完成显式划分 在容器的帮助下完成自动划分 在使用JavaEE的EJB规范时,这两种方案分别被实现为BMT以及CMT,关于BMT和CMT在上一篇文章中有比较详尽的讨论(参考这里). 那么对于Spring Framew

JavaEE中的事务管理——事务划界

前面博文中大致介绍了一下事务,其实在企业应用服务器中事务是在不同的级别上存在的.比较简单的事务是最底层的事务,就是位于资源级别的事务管理.假设数据最终要存储在一个关系型数据库中,那么最底层的事务就是位于这里.我们把这种事务称之为资源本地事务(resource-localtransaction)在不用容器的大部分情况下开发人员要面对的事务都属于这里(其他的事务面对不到是因为水平不够!).理解了数据的事务之后来解决资源本地事务就易如反掌了.如果使用了企业应用服务器那么要处理的大多数事务就是JavaT

JAVAEE——spring03:spring整合JDBC和aop事务

一.spring整合JDBC 1.spring提供了很多模板整合Dao技术 2.spring中提供了一个可以操作数据库的对象.对象封装了jdbc技术. JDBCTemplate => JDBC模板对象 与DBUtils中的QueryRunner非常相似. //0 准备连接池 ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Dri

JavaEE JDBC 事务

JDBC 事务 @author ixenos 事务 1.概念:我们将一组语句构建成一个事务(trans action),当所有语句顺利执行之后,事务可以被提交(commit):否则,如果其中某个语句遇到错误,那么事务将被回滚,就好像没有任何语句被执行一样 2.需求背景:将多个语句组合成事务的主要原因是为了确保数据库完整性(database integrity) 3.默认情况下,数据库连接处于自动提交模式(autocommit mode),每个SQL语句一旦被执行便被提交给数据库,一旦命令被提交就

JavaEE中的事务管理——事务概述(1)

今天打算说一说事务管理,读者可能了解也有可能不了解,其实很简单(大牛请自行绕过).本来想引用个成语的啥的来描述事务的特点,但是搜肠刮肚也没有发现合适的,于是就找了下面几组成语来描述事务性.其实在官方文档中对于事务的描述也是分四个方面来说的.这里算是用自己的理解解释一下罢了. 第一对词语是:"开弓没有回头箭"和"前功尽弃"(功亏一篑?功败垂成?) 这一对词语结合起来看就是事务的原子性,就是我们平时说的要做就做完,要不做就一点儿也不要做.其中前面的做完就是说明这个事务已

JavaEE学习之Spring声明式事务

一.引言 上一篇文章,学习了AOP相关知识,并做了一个简单的Hello world.本文在上篇文章的基础上,进一步学习下Spring的声明式事务. 二.相关概念 1. 事务(Transaction)——它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位 2. 事务的几大特性(A.C.I.D): A——Atomicity(原子性).数据库中的事务执行是作为原子.即不可再分,整个语句要么执行,要么不执行. C——Consistency(一致性).在事务开始之前和事务结束以

【JAVAEE学习笔记】hibernate02:实体规则、对象状态、缓存、事务、批量查询和实现客户列表显示

一.hibernate中的实体规则 实体类创建的注意事项 1.持久化类提供无参数构造 2.成员变量私有,提供共有get/set方法访问.需提供属性 3.持久化类中的属性,应尽量使用包装类型 4.持久化类需要提供oid.与数据库中的主键列对应 5.不要用final修饰class 主键类型 自然主键(少见) 表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用. 代理主键(常见) 表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键

JavaEE Tutorials (22) - 事务

22.1Java EE应用中的事务35222.2什么是事务35322.3容器托管事务353 22.3.1事务属性354 22.3.2回滚容器托管事务357 22.3.3同步会话bean的实例变量357 22.3.4容器托管事务中不允许的方法35822.4bean托管事务358 22.4.1JTA事务358 22.4.2不提交返回359 22.4.3bean托管事务中不允许的方法35922.5事务超时359 22.5.1设置事务超时35922.6更新多个数据库36022.7Web组件中的事务361