大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
如何用java开启mysql事务,要求详细
成都创新互联从2013年成立,先为定边等服务建站,定边等地企业,进行企业商务咨询服务。为定边企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
看你是什么事务,jdbc事务,还是分布式事务,还是容器事务
1,编程式事务管理(jdbc的事务是绑定在connection上的)
Connection conn = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","password");
conn.setAutoCommit(false); //取消自动提交
PreparedStatement ps = conn.prepareCall("update something");
ResultSet rs = ps.executeQuery();
conn点抗 mit(); //手动提交
}
catch (Exception e)
{
conn.rollback();
e.printStackTrace();
}
finally
{
conn.close();
}
2,声明式事务
先在工程的application.xml配置文件中添加如下代码,开启事务
!-- 声明式事务控制配置 --
tx:annotation-driven transaction-manager="txManager"/
bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="datasource" ref="bassDataSource"/property
/bean
然后在你需要开启事务的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再类里和方法里面添加事务注解0~0");
throw new IOException();
}
直接调用接口方法就好
分布式事务处理(mysql貌似在5.X之后才支持) 的话,
1.可以直接使用spring+atomikos框架进行管理
参考:
就不贴测试代码了,自己看着配置吧
2,使用JTA(Java Transaction API)进行分布式事务管理(测试代码如下)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
//分布式事务处理
public class transferAccount
{
@SuppressWarnings("null")
public void testTransferAccount()
{
UserTransaction userts = null;
Connection connA = null;
PreparedStatement psA = null;
InitialContext context = null;
Connection connB = null;
PreparedStatement psB = null;
try
{
//获得事务管理对象
userts = (UserTransaction) context.lookup("java:comp/UserTransaction");
//获取两个数据库
connA = getDataSourceA().getConnection();
connB = getDataSourceB().getConnection();
//开启事务
userts.begin();
//sql语句
psA = connA.prepareStatement("我加1");
psB = connB.prepareStatement("我减1");
//执行sql
psA.executeUpdate();
psB.executeUpdate();
//事务提交
userts点抗 mit();
} catch (Exception e)
{
try
{
userts.rollback();
} catch (IllegalStateException | SecurityException
| SystemException e1)
{
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try
{
psA.close();
psB.close();
connA.close();
connB.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
public DataSource getDataSourceA()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1433);
dataSource.setUser("test");
dataSource.setPassword("test");
return dataSource;
}
public DataSource getDataSourceB()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1435);
dataSource.setUser("test1");
dataSource.setPassword("test1");
return dataSource;
}
}
; 事务处理是企业应用需要解决的最主要的问题之一 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 reduceInventory(conn bookId quantity)){ BigDecimal price=BookDAO getPrice(bookId); //取价格 //从客户帐户中扣除price*quantity的费用 b= CustomerDAO reduceAccount(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外部对象 它的代码其实很简单 如果不了解动态代理技术的请先阅读其他资料
lishixinzhi/Article/program/Java/gj/201311/27765
如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前的操作.....
JavaBean中使用JDBC方式进行事务处理
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事务的默认提交方式
dbc.executeUpdate("delete from xiao where ID=" + sID);
dbc.executeUpdate("delete from xiao_content where ID=" + sID);
dbc.executeUpdate("delete from xiao_affix where bylawid=" + sID);
con点抗 mit();//提交JDBC事务
con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滚JDBC事务
exc.printStackTrace();
dbc.close();
return -1;
}
}
在数据库操作中,一项事务是指由一条或多条对数据库更新的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作没有完成,就必须撤消整个事务。
例如在银行的转帐事务中,假定张三从自己的帐号上把1000元转到李四的帐号上,相关的sql语句如下:
update account set monery=monery-1000 where name='zhangsan'
update account set monery=monery+1000 where name='lisi'
这个两条语句必须作为一个完成的事务来处理。只有当两条都成功执行了,才能提交这个事务。如果有一句失败,整个事务必须撤消。
在connection类中提供了3个控制事务的方法:
(1) setAutoCommit(Boolean autoCommit):设置是否自动提交事务;
(2) commit();提交事务;
(3) rollback();撤消事务;
在jdbc api中,默认的情况为自动提交事务,也就是说,每一条对数据库的更新的sql语句代表一项事务,操作成功后,系统自动调用commit()来提交,否则将调用rollback()来撤消事务。
在jdbc api中,可以通过调用setAutoCommit(false) 来禁止自动提交事务。然后就可以把多条更新数据库的sql语句做为一个事务,在所有操作完成之后,调用commit()来进行整体提交。倘若其中一项sql操作失败,就不会执行commit()方法,而是产生相应的sqlexception,此时就可以捕获异常代码块中调用rollback()方法撤消事务。