java中事务
‘壹’ java事务的特性有哪些
ACID特征
Atomic原子性、Consistency一致性、Isolation隔离性和Durability持久性。
原子性:指整个事务是不可以分割的工作单元。只有事务中所有的操作执行成功,才算整个事务成功,事务中任何一个sql语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该回到执行事务前的状态。
一致性:指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对于银行转账事务,不管事务成功还是失败,应该保证事务结束后两个转账账户的存款总额是与转账前一致的。
隔离性:指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
持久性:指的是只要事务成功结束它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
‘贰’ java如何进行事务管理,什么时候用事务控制
Java种运用了大量的事务管理,就是对一系列的数据库操作进行统一的提交或回滚操作,比如说做一个转账功能,要更改帐户两边的数据,这时候就必须要用事务才能算是严谨的做法。要么成功,要么失败,保持数据一致性。如果中间有一个操作出现异常,那么回滚之前的所有操作。
在strut2框架中为了避免多个用户同时访问服务器,都会使用事务管理来管理访问的人数。
‘叁’ java中的事务
如果你用Spring框架,Spring中可以实现事务管理,在spring 配置文件中配置事务管理器,也可以使用Spring注解式事务,在方法上加上@Transactional注解。
@Transactional
public void save() {
//你的代码逻辑
}
如果没有使用Spring框架,可以用JDBC处理事务,如下:
try{
con.setAutoCommit(false);//开启事务 ......
con.commit();//try的最后提交事务
} catch() {
con.rollback();//回滚事务
}
‘肆’ java中多个事务公用一个连接吗
spring事务
数据库事务、连接与java线程之间的关系
最近在处理事务和多线程时,比较困扰数据库事务,数据库连接以及java线程之间的关系。
问题1:事务和连接的关系?
回答:对于数据库事务来说先有一个连接,才能有事务,一个连接里可以有一次或多次事务的提交(自动提交或者手动提交)。对于java中的被transactional注解方法来说,这个被事务管理的方法中可能会使用多个连接。例如一个事务方法里嵌套一个propagation=required的事务方法时,外方法用一个连接,嵌套的方法用一个连接,并且是两个不同的事务。
问题2:连接和线程的关系?
回答:从debug代码看来,一个线程中有去操作数据库,就会去CP获取一个数据库连接,如果此时CP中没有连接可用,就会等待,直到有连接为止。
问题3:一个事务中(transactional注解的方法内)如果开启了多个线程去执行其他的插入操作,那么每个线程执行的插入操作,和线程的caller方法中的插入操作是同一个事务吗?
回答:不是同一个事务
解析:
1.如下图,一个transactional 注解的方法内,先做一次插入操作,接着开了3个线程去分别处理插入任务
2.执行结果通过看debug日志可看出,在执行testTransAndConnection方法时获取了一个数据库连接,并开启了一个事务,并把事务设置为手动提交,然后进行插入操作,插入操作完成,就call起三个线程并且准备着手提交主方法里的事务了。
3.每个线程是创建了不同的sqlsession 去处理的,这里用的连接却都还是主方法释放的那个连接(这里都是同一个连接的原因是由于服务起来后,第一次去请求应用,此时数据库连接池还没有初始化完毕,池子里只有刚刚初始化好的一个连接,其他的连接还没来的及初始化出来,所以这里几个线程的操作其实是大家都在等待并争用那唯一的一个数据库连接。等CP初始化完毕,如果再次触发一次请求就会发现:每个线程的sqlsession都是不同的连接)
‘伍’ 如何在JAVA中实现事务呢
事务一般都是与数据库操作相关的,直接使用JDBC的话,你可以通过设置是否自动commit,以及出异常后rollback来实现事务,如果你使用spring、hibernate等框架,它都会提供相应的事务配置。
‘陆’ java事务相关
Java中的事务处理
一般情况下,J2EE应用服务器支持JDBC事务、JTA(JavaTransactionAPI)事务、容器管理事务。一般情况下,最好不要在程序中同时使用上述三种事务类型,比如在JTA事务中嵌套JDBC事务。第二方面,事务要在尽可能短的时间内完成,不要在不同方法中实现事务的使用。下面我们列举两种事务处理方式。
1、JavaBean中使用JDBC方式进行事务处理
在JDBC中怎样将多个SQL语句组合成一个事务呢?在JDBC中,打开一个连接对象Connection时,缺省是auto-commit模式,每个SQL语句都被当作一个事务,即每次执行一个语句,都会自动的得到事务确认。为了能将多个SQL语句组合成一个事务,要将auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不调用commit()方法,SQL语句不会得到事务确认。在最近一次commit()方法调用之后的所有SQL会在方法commit()调用时得到确认。
publicintdelete(intsID){
dbc=newDataBaseConnection();
Connectioncon=dbc.getConnection();
try{
con.setAutoCommit(false);//更改JDBC事务的默认提交方式
dbc.executeUpdate("deletefrombylawwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_contentwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_affixwherebylawid="+sID);
con.commit();//提交JDBC事务
con.setAutoCommit(true);//恢复JDBC事务的默认提交方式
dbc.close();
return1;
}
catch(Exceptionexc){
con.rollBack();//回滚JDBC事务
exc.printStackTrace();
dbc.close();
return-1;
}
}
2、SessionBean中的JTA事务
JTA是事务服务的J2EE解决方案。本质上,它是描述事务接口(比如UserTransaction接口,开发人员直接使用该接口或者通过J2EE容器使用该接口来确保业务逻辑能够可靠地运行)的J2EE模型的一部分。JTA具有的三个主要的接口分别是UserTransaction接口、TransactionManager接口和Transaction接口。这些接口共享公共的事务操作,例如commit()和rollback(),但是也包含特殊的事务操作,例如suspend(),resume()和enlist(),它们只出现在特定的接口上,以便在实现中允许一定程度的访问控制。例如,UserTransaction能够执行事务划分和基本的事务操作,而TransactionManager能够执行上下文管理。
应用程序可以调用UserTransaction.begin()方法开始一个事务,该事务与应用程序正在其中运行的当前线程相关联。底层的事务管理器实际处理线程与事务之间的关联。UserTransaction.commit()方法终止与当前线程关联的事务。UserTransaction.rollback()方法将放弃与当前线程关联的当前事务。
publicintdelete(intsID){
DataBaseConnectiondbc=null;
dbc=newDataBaseConnection();
dbc.getConnection();
UserTransactiontransaction=sessionContext.getUserTransaction();//获得JTA事务
try{
transaction.begin();//开始JTA事务
dbc.executeUpdate("deletefrombylawwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_contentwhereID="+sID);
dbc.executeUpdate("deletefrombylaw_affixwherebylawid="+sID);
transaction.commit();//提交JTA事务
dbc.close();
return1;
}
catch(Exceptionexc){
try{
transaction.rollback();//JTA事务回滚
}
catch(Exceptionex){
//JTA事务回滚出错处理
ex.printStackTrace();
}
exc.printStackTrace();
dbc.close();
return-1;
}
}
‘柒’ JAVA设计模式之事务处理[1]
事务处理是企业应用需要解决的最主要的问题之一 J EE通过JTA提供了完整的事务管理能力 包括多个事务性资源的管理能力 但是大部分应用都是运行在单一的事务性资源之上(一个数据库) 他们并不需要全局性的事务服务 本地事务服务已然足够(比如JDBC事务管理) 本文并不讨论应该采用何种事务处理方式 主要目的是讨论如何更为优雅地设计事务服务 仅以JDBC事务处理为例 涉及到的DAO Factory Proxy Decorator等模式概念 请阅读相关资料 也许你听说过 事务处理应该做在service层 也许你也正这样做 但是否知道为什么这样做?为什么不放在DAO层做事务处理 显而易见的原因是业务层接口的每一个方法有时候都是一个业务用例(User Case) 它需要调用不同的DAO对象来完成一个业务方法 比如简单地以网上书店购书最后的确定定单为例 业务方法首先是调用BookDAO对象(一般是通过DAO工厂产生) BookDAO判断是否还有库存余量 取得该书的价格信息等 然后调用CustomerDAO从帐户扣除相应的费用以及记录信息 然后是其他服务(通知管理员等) 简化业务流程大概如此: 注意 我们的例子忽略了连接的处理 只要保证同一个线程内取的是相同的连接即可(可用ThreadLocal实现)首先是业务接口 针对接口 而不是针对类编程
public interface BookStoreManager{ public boolean buyBook(String bookId int quantity)throws SystemException; 其他业务方法 }
接下来就是业务接口的实现类??业务对象
public class BookStoreManagerImpl implements BookStoreManager{ public boolean buyBook(String bookId)throws SystemException{ Connection conn=ConnectionManager getConnection();//获取数据库连接 boolean b=false; try{ conn setAutoCommit(false); //取消自动提交 BookDAO bookDAO=DAOFactory getBookDAO(); CustomerDAO customerDAO=DAOFactory getCustomerDAO(); //尝试从库存中取书 if(BookDAO receInventory(conn bookId quantity)){ BigDecimal price=BookDAO getPrice(bookId); //取价格 //从客户帐户中扣除price*quantity的费用 b= CustomerDAO receAccount(conn price multiply(new BigDecimal(quantity)); 其他业务方法 如通知管理员 生成定单等 conn mit(); //提交事务 conn setAutoCommit(true); } }catch(SQLException e){ conn rollback(); //出现异常 回滚事务 con setAutoCommit(true); e printStackTrace(); throws new SystemException(e); } return b; } }
然后是业务代表工厂
public final class ManagerFactory { public static BookStoreManager getBookStoreManager() { return new BookStoreManagerImpl(); } }
这样的设计非常适合于DAO中的简单活动 我们项目中的一个小系统也是采用这样的设计方案 但是它不适合于更大规模的应用 首先 你有没有闻到代码重复的 bad *** ell?每次都要设置AutoCommit为false 然后提交 出现异常回滚 包装异常抛到上层 写多了不烦才怪 那能不能消除呢?其次 业务代表对象现在知道它内部事务管理的所有的细节 这与我们设计业务代表对象的初衷不符 对于业务代表对象来说 了解一个与事务有关的业务约束是相当恰当的 但是让它负责来实现它们就不太恰当了 再次 你是否想过嵌套业务对象的场景?业务代表对象之间的互相调用 层层嵌套 此时你又如何处理呢?你要知道按我们现在的方式 每个业务方法都处于各自独立的事务上下文当中(Transaction Context) 互相调用形成了嵌套事务 此时你又该如何处理?也许办法就是重新写一遍 把不同的业务方法集中成一个巨无霸包装在一个事务上下文中
我们有更为优雅的设计来解决这类问题 如果我们把Transaction Context的控制交给一个被业务代表对象 DAO和其他Component所共知的外部对象 当业务代表对象的某个方法需要事务管理时 它提示此外部对象它希望开始一个事务 外部对象获取一个连接并且开始数据库事务 也就是将事务控制从service层抽离 当web层调用service层的某个业务代表对象时 返回的是一个经过Transaction Context外部对象包装(或者说代理)的业务对象 此代理对象将请求发送给原始业务代表对象 但是对其中的业务方法进行事务控制 那么 我们如何实现此效果呢?答案是JDK 引进的动态代理技术 动态代理技术只能代理接口 这也是为什么我们需要业务接口BookStoreManager的原因 首先 我们引入这个Transaction Context外部对象 它的代码其实很简单 如果不了解动态代理技术的请先阅读其他资料
lishixin/Article/program/Java/gj/201311/27765
‘捌’ 事务是什么在java中如何手工执行事务
举个例子,银行转账就是一个事物:从A账户减去金额,吧该金额转到B账户中。吧所有操作完成并且数据同步到数据库中,事物才栓完成。但是数据库操作过程中可能发生错误,其中一个操作失败,就会造成A+B账户金额与操作前的有出入,当发生错误后要取消操作(数据库的事物回滚),保证数据的一致性。
手工执行事物:
1、关闭数据库自动提交,
2、数据库操作完成后如果出错:回滚;没有错误:提交
3、记得关闭数据库连接
‘玖’ Java 编程 ,事务管理的作用
事务就是对一系列的数据库操作进行统一的提交或回滚操作,比如说做一个转账功能,要更改帐户两边的数据,这时候就必须要用事务才能算是严谨的做法。要么成功,要么失败,保持数据一致性。如果中间有一个操作出现异常,那么回滚之前的所有操作。
这样有什么好处呢。
这样可以防止在一些意外(例如说突然断电)的情况下出现乱数据,防止数据库数据出现问题。这边加了钱,那边却还是一样的数,这就完了。要是开放一个网上交易的平台,这样就会出大问题的!
还有其他的一些操作,像是要添加多条数据,如果程序要求必须全部正确才能插入的话,事务又起大作用了。
等等。。。开发中为了避免这种情况一般都会进行事务管理。
在JDBC中是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。
Hibernate中是通过Transaction进行事务管理,处理方法与JDBC中类似。
Spring中也有自己的事务管理机制,使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。
‘拾’ 如何手动控制java中的事务
很简单,直接将autoCommit设置为false,就可以自己控制事务的提交和回滚!
大概是:conn.setAutoCommit(false);这个方法,然后开启事务是:conn.beginTrainsaction();方法如有不准确,希望海涵!