- 浏览: 31965 次
- 性别:
- 来自: 上海
最新评论
概述:
为了学习事务的管理,实现了如下的一个简单版本的事务管理器,进行实验。该管理器简化了事务管理的各种异常类型的考虑。
对于Transaction 管理
为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
常见的代码如下:
在以上的代码中与业务逻辑相关的代码只有一行, 为了简化事务的操作,实现一个简单的事务管理控制。主要提供以下方面的统一控制。
1.使用回调机制简化事务处理的代码
2.增加对事务隔离级别的支持
3.增加事务Timeout的管理,最简单的实现。 尽早发现长事务的操作。
4.对于savepoint的支持
5.实现一种事务传播控制。 如果当前存在事务,就加入该事务中执行,如果没有新建事务,放到事务中实现。
实现了该事务控制管理器后,将Service的代码得到如下的简化:
1. 回调的实现
定义模板类TransactionTemplate
其主要的方法就是提供模板方法对事务处理的代码进行控制:
2. 回调接口的定义非常的简单:
3. 重点Transaction类的实现,管理了Connection对象,事务隔离级别的定义,事务的savepoint控制点,以及对于事务状态的控制。
1) 对于savePoints属性记录了所有的事务的保存点,当service运行抛出Exception时,将进入rollback逻辑,这个时候,rollback方法会查找相应的Exception的保存点,将事务回滚到该保存点。
具体的保存点检查代码如下:
public void addSavepointAndRollbackException(String name, Exception e)
public boolean isSupportSavepoint() throws SQLException{}
private Savepoint addSavePoint(String savepointName) throws SQLException{}
public boolean containsSavepoint() {}
public Savepoint getSavePointByException(Exception e) {}
2) 属性newTrCount主要是用于实现事务的传播控制。当且仅当该值为1时候表示该事务是新创建的一个事务。当一个service运行的时候,如果发现当前的service线程已经有事务对象,那么这个时候就不需要再重新创建事务,只需要将原有的事务对象的计数器加1,那么相应的当该Serice运行完成才将事务减一,从而保证只有最外层的service看到的事务对象是新创建的事务对象,会执行真正的事务操作,而其他嵌套的Service对象,只是对该count进行操作。
提供了如下的三个方法方便控制:
public void addNewService(){
this.newTrCount++;
}
public void completeService(){
this.newTrCount--;
}
public boolean isNewTransaction(){
return this.newTrCount == 1;
}
4. 核心对象TransactionManager 该对象管理了Transaction对象,并且控制着事务的操作。
其代码如下
5. ConnectionManager对象的实现
为了学习事务的管理,实现了如下的一个简单版本的事务管理器,进行实验。该管理器简化了事务管理的各种异常类型的考虑。
对于Transaction 管理
为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
常见的代码如下:
public void doService(){ Connection connection = getConnection(); connection.setTransactionIsolation( Connection.TRANSACTION_READ_COMMITTED); try{ doBusinessLogic(connection); connection.commit(); }catch(Exception e){ connection.rollback(); }finally{ connection.close(); } }
在以上的代码中与业务逻辑相关的代码只有一行, 为了简化事务的操作,实现一个简单的事务管理控制。主要提供以下方面的统一控制。
1.使用回调机制简化事务处理的代码
2.增加对事务隔离级别的支持
3.增加事务Timeout的管理,最简单的实现。 尽早发现长事务的操作。
4.对于savepoint的支持
5.实现一种事务传播控制。 如果当前存在事务,就加入该事务中执行,如果没有新建事务,放到事务中实现。
实现了该事务控制管理器后,将Service的代码得到如下的简化:
private Service service; private Dao dao; private TransactionTemplate transactionTemplate; public void service(final Object obj) { this.trTemplate.executeTransaction(new TransactionCallback(){ public Object doTransactionEvent() { service.doService(); transactionTemplate.addSavePoint("savepoint1", exception1); dao.saveMethod1(obj); transactionTemplate.addSavePoint("savepoint2", exception2); dao.saveMethod2(obj); } }); }
1. 回调的实现
定义模板类TransactionTemplate
其主要的方法就是提供模板方法对事务处理的代码进行控制:
public class TransactionTemplate { private TransactionManager trManager; //the timeout monitor is used to find out all long time transaction in advance. private boolean useTimeoutMonitor = Boolean.TRUE; private Long maxTime = Long.valueOf(2); public void addSavePoint(String savePointName, Exception rollbackException){ this.trManager.addSavePoint(savePointName, rollbackException); } public void executeTransaction( TransactionCallback transactionCallback, int isolationLevel) { long startTime = System.currentTimeMillis(); Transaction transaction = null; try{ transaction = trManager.beginTransaction(); checkTimeout(startTime); transaction.setTransactionIsolationLevel(isolationLevel); transactionCallback.doTransactionEvent(); checkTimeout(startTime); trManager.commitTransaction(transaction); }catch(Exception e){ trManager.rollbackTransaction(transaction, e); }finally{ trManager.closeTransaction(transaction); } } /** * If the transaction is timeout throw a transaction time out exception. */ private void checkTimeout(long startTime) { if( this.useTimeoutMonitor ){ if(isTimeout(startTime)){ throw new TransactionTimeoutException(); } } } private boolean isTimeout(long startTime) { return System.currentTimeMillis() - startTime > this.maxTime ; } public void executeTransaction(TransactionCallback transactionCallback){ this.executeTransaction(transactionCallback, Transaction.DEFAULT_ISOLATION_LEVEL); } public Long getMaxTime() { return maxTime; } public void setMaxTime(Long maxTime) { this.maxTime = maxTime; } }
2. 回调接口的定义非常的简单:
public interface TransactionCallback { public Object doTransactionEvent(); }
3. 重点Transaction类的实现,管理了Connection对象,事务隔离级别的定义,事务的savepoint控制点,以及对于事务状态的控制。
public class Transaction { public static final int READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED; public static final int READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED; public static final int REPEATALB_READ = Connection.TRANSACTION_REPEATABLE_READ; public static final int SERIALIZE = Connection.TRANSACTION_SERIALIZABLE; public static final int DEFAULT_ISOLATION_LEVEL = READ_COMMITTED; private Map<Exception,Savepoint> savePoints = new HashMap<Exception, Savepoint>(); //This count is used to implement the transaction propagation private int newTrCount = 1; Connection connection; public Transaction(Connection connection){ this.connection = connection; } public void addNewService(){ this.newTrCount++; } public void completeService(){ this.newTrCount--; } public boolean isNewTransaction(){ return this.newTrCount == 1; } /** * @return the connection */ public Connection getConnection() { return connection; } /** * @param connection the connection to set */ public void setConnection(Connection connection) { this.connection = connection; } /** * @param transactionIsolationLevel the transactionIsolationLevel to set * @throws SQLException */ public void setTransactionIsolationLevel(int transactionIsolationLevel) throws SQLException { this.connection.setAutoCommit(false); this.connection.setTransactionIsolation(transactionIsolationLevel); } public void addSavepointAndRollbackException(String name, Exception e) throws SQLException{ Savepoint savepoint = this.addSavePoint(name); this.savePoints.put(e, savepoint); } public boolean isSupportSavepoint() throws SQLException{ return this.getConnection().getMetaData().supportsSavepoints(); } private Savepoint addSavePoint(String savepointName) throws SQLException{ return this.connection.setSavepoint(savepointName); } public boolean containsSavepoint() { return !this.savePoints.isEmpty(); } public Savepoint getSavePointByException(Exception e) { return this.savePoints.get(e); } }
1) 对于savePoints属性记录了所有的事务的保存点,当service运行抛出Exception时,将进入rollback逻辑,这个时候,rollback方法会查找相应的Exception的保存点,将事务回滚到该保存点。
具体的保存点检查代码如下:
public void addSavepointAndRollbackException(String name, Exception e)
public boolean isSupportSavepoint() throws SQLException{}
private Savepoint addSavePoint(String savepointName) throws SQLException{}
public boolean containsSavepoint() {}
public Savepoint getSavePointByException(Exception e) {}
2) 属性newTrCount主要是用于实现事务的传播控制。当且仅当该值为1时候表示该事务是新创建的一个事务。当一个service运行的时候,如果发现当前的service线程已经有事务对象,那么这个时候就不需要再重新创建事务,只需要将原有的事务对象的计数器加1,那么相应的当该Serice运行完成才将事务减一,从而保证只有最外层的service看到的事务对象是新创建的事务对象,会执行真正的事务操作,而其他嵌套的Service对象,只是对该count进行操作。
提供了如下的三个方法方便控制:
public void addNewService(){
this.newTrCount++;
}
public void completeService(){
this.newTrCount--;
}
public boolean isNewTransaction(){
return this.newTrCount == 1;
}
4. 核心对象TransactionManager 该对象管理了Transaction对象,并且控制着事务的操作。
其代码如下
public class TransactionManager { private ConnectionManager connectionManager; private ThreadLocal<Transaction> transactions = new ThreadLocal<Transaction>(); public Transaction beginTransaction() { try{ Transaction tr = this.transactions.get(); if( tr == null ){ Connection connection = connectionManager.getConnection(); connectionManager.setTransactionActive(true); tr = new Transaction(connection); this.transactions.set(tr); }else{ tr.addNewService(); } return tr; }catch(Exception e){ throw new TransactionException(); } } public void commitTransaction(Transaction transaction) { try{ if( transaction.isNewTransaction() ){ connectionManager.setTransactionActive(false); connectionManager.commit(transaction.getConnection()); } }catch(Exception e){ throw new TransactionException(); } } public void rollbackTransaction(Transaction transaction, Exception e) { try{ if( transaction.isNewTransaction() ){ connectionManager.setTransactionActive(false); if(transaction.containsSavepoint()){ Savepoint savepoint = transaction.getSavePointByException(e); if( savepoint == null ){ connectionManager.rollback(transaction.getConnection()); }else{ connectionManager.rollback(transaction.getConnection(), savepoint); } }else{ connectionManager.rollback(transaction.getConnection()); } } }catch( Exception e2){ throw new TransactionException(); } } public void closeTransaction(Transaction transaction){ try{ if( transaction.isNewTransaction() ){ this.transactions.remove(); connectionManager.setTransactionActive(false); connectionManager.releaseConnection(transaction.getConnection()); }else{ transaction.completeService(); } }catch(Exception e){ throw new TransactionException(); } } /** * @return * @throws ClassNotFoundException * @throws SQLException */ /** * @return the connectionManager */ public ConnectionManager getConnectionManager() { return connectionManager; } /** * @param connectionManager the connectionManager to set */ public void setConnectionManager(ConnectionManager connectionManager) { this.connectionManager = connectionManager; } public void addSavePoint(String savePointName, Exception rollbackException){ Transaction tr = this.transactions.get(); if(tr == null){ tr = this.beginTransaction(); } try{ if(!tr.isSupportSavepoint()){ throw new SavePointNotSupportException(); } tr.addSavepointAndRollbackException(savePointName, rollbackException); }catch(Exception e){ throw new TransactionException(); } } }
5. ConnectionManager对象的实现
public class ConnectionManager { private static ConnectionManager connectionManager = new ConnectionManager(); ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>(); private ConnectionManager(){} public static ConnectionManager getConnectionManager(){ return connectionManager; } private Boolean isTransactionActive = Boolean.FALSE; public Connection getConnection() throws ClassNotFoundException, SQLException{ Connection connection = this.threadConnection.get(); if( connection == null ){ connection = (Connection) DriverManager.getConnection ( "jdbc:sqlserver://10.171.30.11:1433;instanceName=nasa;databaseName=nasa2_SMS_PT;SelectMethod=cursor;characterEncoding=utf-8;autoReconnectForPools=true;autoReconnect=true", "sms", "sms"); this.threadConnection.set(connection); } return connection; } public void releaseConnection(Connection connection) throws SQLException{ if( !isTransactionActive ){ threadConnection.remove(); connection.close(); } } public void commit(Connection connection) throws SQLException{ if( !isTransactionActive ){ connection.commit(); } } public void rollback(Connection connection) throws SQLException{ if( !isTransactionActive ){ connection.rollback(); } } public void rollback(Connection connection, Savepoint savepoint) throws SQLException{ if( !isTransactionActive ){ connection.rollback(savepoint); } } /** * @param isTransactionFinished the isTransactionFinished to set */ public void setTransactionActive(Boolean isTransactionActive) { this.isTransactionActive = isTransactionActive; } }
相关推荐
- **数据库供应商提供的JDBC驱动**:由数据库厂商如Oracle、MySQL、SQL Server等实现,提供原生的Java支持。 3. **JDBC API**: - **DriverManager类**:负责管理数据库驱动,加载并注册驱动,以及创建数据库连接...
jdbc——内嵌事务 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> ...
《基于JSP技术的猎头公司管理软件的设计与实现——内部事务部分》 本文主要探讨的是如何运用JSP(JavaServer Pages)技术开发一款适用于猎头公司的管理软件,特别是其内部事务处理模块。JSP是一种动态网页技术,它...
首先,让我们了解JDBC事务管理。在JDBC中,事务的开始、提交和回滚可以通过Connection对象来控制。`setAutoCommit(false)`会禁用自动提交,这时就需要手动调用`commit()`或`rollback()`来决定事务的最终状态。例如:...
JDBC事务管理器适用于简单的应用程序,而Spring事务管理器更适合于使用Spring框架的项目,因为它提供了更高级的事务控制和回滚策略。 4. **SqlSessionFactory和SqlSession的角色**:SqlSessionFactory是MyBatis的...
本案例重点探讨了Spring如何与两种流行的数据访问技术——JDBC(Java Database Connectivity)和Hibernate——相结合,进行事务管理。事务控制是确保数据库操作一致性、完整性的关键,尤其在多步骤操作中,它能防止...
《基于JSP技术的猎头公司管理软件设计与实现——内部事务部分》 本文将深入探讨如何利用Java的JSP(JavaServer Pages)技术来设计并实现一款针对猎头公司的内部事务管理软件。该软件旨在优化猎头公司的日常工作流程...
学习JDBC和MySQL的基础知识,不仅可以帮助你理解和操作数据库,还可以为进一步深入学习数据库设计、SQL优化、事务处理、存储过程等高级主题打下坚实基础。在实际开发中,熟练掌握JDBC能有效提升数据操作的效率和代码...
《基于JSP技术的猎头公司管理软件设计与实现——内部事务部分》 本文将深入探讨一款基于JSP(JavaServer Pages)技术的猎头公司管理软件的设计与实现,主要关注其内部事务处理部分。JSP是Java平台上的动态网页开发...
**示例:传统的JDBC事务管理** 在使用JDBC进行数据操作时,传统的事务管理通常涉及到手动管理`Connection`对象的获取、开启事务、执行SQL、提交或回滚事务等步骤。这种方式不仅代码量大,而且容易出错。 ```java ...
《基于JSP技术的猎头公司管理软件设计与实现——内部事务部分》 在现代商业环境中,猎头公司扮演着连接企业与人才的关键角色。为了提高业务效率和管理水平,开发一款基于JSP技术的猎头公司管理软件显得尤为重要。本...
5. **事务管理**:使用Connection对象的`setAutoCommit()`和`commit()`方法控制事务的提交和回滚。 6. **连接池**:在大型应用中,使用连接池(如C3P0、HikariCP)可以有效管理和复用数据库连接,提高系统性能。 7. ...
【JDBC事务】 在Java数据库连接(JDBC)中,事务是...总之,理解并熟练掌握JDBC事务管理对于编写健壮的数据库应用程序至关重要。通过控制事务,我们可以确保数据的准确性和一致性,防止并发问题,同时优化系统的性能。
【标题】中的“基于JSP技术的猎头公司管理软件的设计和实现——内部事务部分”表明,这是一个关于使用JavaServer Pages (JSP) 技术开发的管理软件项目,主要关注的是猎头公司的内部事务处理。JSP是Java平台上的一个...
5、JDBC事务特性及常用方法: - 事务特性包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),简称ACID。 - 常用方法: - Connection的setAutoCommit()方法用于开启或...
《关键技术——JSP与JDBC应用详解》这本书深入探讨了Java服务器页面(JSP)和Java数据库连接(JDBC)这两个在Web开发中至关重要的技术。对于任何希望在Java平台上进行Web应用程序开发的程序员来说,理解和掌握这两项...
《基于JSP技术的猎头公司管理软件设计与实现——内部事务部分》 本文将深入探讨一个毕业设计项目,即采用JavaServer Pages (JSP) 技术开发的猎头公司管理软件,主要关注其内部事务处理部分。JSP是一种在服务器端...
在 Spring Boot 应用中,通常只需要简单的配置就可以启用事务管理功能。 ##### 1. 自动配置 Spring Boot 自动配置了许多常用的事务管理器,如 `DataSourceTransactionManager` 和 `JpaTransactionManager`。这意味...