事务控制代码示例

1 JDBC事务 
这个没啥好说的,直接上代码 
public class JdbcTransactionMain { 
    public static void main(String[] args) throws Exception{ 
        Class.forName("com.mysql.jdbc.Driver"); 
        Connection conn = null; 
        Statement st = null; 
        try{ 
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/springdemo","root","frank1234"); 
            //开始事务 
            conn.setAutoCommit(false); 
            st = conn.createStatement(); 
            st.executeUpdate("insertsql1"); 
            st.executeUpdate("insertsql2"); 
            //事务提交 
            conn.commit(); 
        }catch (Exception e){ 
            e.printStackTrace(); 
            //注意有异常必须得回滚,否则执行成功的sql会持久化到数据库中 
            conn.rollback(); 
        }finally {//记得释放资源 
            if(st != null) 
                st.close(); 
            if(conn != null) 
                conn.close(); 
        } 
    } 



2 Hibernate事务 

public class HibernateTransactionMain { 
    public static void main(String[] args) throws Exception{ 
        Session session = null; 
        Transaction tx = null; 
        try { 
            session = new Configuration().configure().buildSessionFactory().openSession(); 
            //开始事务 
            tx = session.beginTransaction(); 
            session.save(po1); 
            session.save(po2); 
            //提交事务 
            tx.commit(); 
        }catch (Exception e){ 
            e.printStackTrace(); 
            //回滚事务 
            tx.rollback(); 
        }finally { 
            if(session != null) 
                session.close(); 
        } 
    } 



3 Spring声明式事务 
下面代码示例操作数据库使用Sping的JdbcTemplate 
后台数据库表: 
CREATE TABLE `person` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `name` varchar(20) DEFAULT NULL, 
  `sex` varchar(2) DEFAULT NULL, 
  `age` int(11) DEFAULT NULL, 
  PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 

CREATE TABLE `orders` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `cost` int(11) NOT NULL, 
  `customerid` int(11) NOT NULL, 
  PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 

Person对象 
public class Person { 

     /** 
      * id号 
      */ 
     private int id; 
     /** 
      * 姓名 
      */ 
     private String name; 
     /** 
      * 年龄 
      */ 
     private int age; 
     /** 
      * 性别 
      */ 
     private String sex; 


     public Person(int id, String name, int age, String sex) { 
         this.id = id; 
         this.name = name; 
         this.age = age; 
         this.sex = sex; 
     } 

     public Person() { 
     } 

     public int getId() { 
         return id; 
     } 

     public void setId(int id) { 
         this.id = id; 
     } 

     public String getName() { 
         return name; 
     } 

     public void setName(String name) { 
         this.name = name; 
     } 

     public int getAge() { 
         return age; 
     } 

     public void setAge(int age) { 
         this.age = age; 
     } 

     public String getSex() { 
         return sex; 
     } 

     public void setSex(String sex) { 
         this.sex = sex; 
     } 



Order对象: 
public class Order { 
    private int id; 
    private int cost; 
    private int customerId; 
    public int getId() { 
        return id; 
    } 

    public void setId(int id) { 
        this.id = id; 
    } 

    public int getCost() { 
        return cost; 
    } 

    public void setCost(int cost) { 
        this.cost = cost; 
    } 

    public int getCustomerId() { 
        return customerId; 
    } 

    public void setCustomerId(int customerId) { 
        this.customerId = customerId; 
    } 

    public String toString(){ 
        return "id="+id+",cost="+cost; 
    } 



TransactionDAO接口: 
public interface TransactionDAO { 
    public void savePersonAndOrder(Person person,Order order); 
    public void savePerson(Person person); 
    public void saveOrder(Order order); 


TransactionDAOImpl实现类: 
其中saveOrder()方法写错,让其操作不成功。 
public class TransactionDAOImpl implements TransactionDAO{ 
    private JdbcTemplate jdbcTemplate; 

    public void setDataSource(DataSource dataSource) { 
        this.jdbcTemplate = new JdbcTemplate(dataSource); 
    } 

    public void savePersonAndOrder(Person person,Order order) { 
        savePerson(person); 
        saveOrder(order); 
    } 

    public void savePerson(Person person) { 
        jdbcTemplate.update("insert into person(name,age,sex)values(?,?,?)", 
                new Object[] { person.getName(), person.getAge(), 
                        person.getSex() }, new int[] { java.sql.Types.VARCHAR, 
                        java.sql.Types.INTEGER, java.sql.Types.VARCHAR }); 

    } 

    public void saveOrder(Order order) { 
        jdbcTemplate.update("insert into order1(cost,customerid)values(?,?)", 
                new Object[] { order.getCost(), order.getCustomerId()}, new int[] { 
                        java.sql.Types.INTEGER, Types.INTEGER }); 
    } 



Spring配置文件: 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> 
<beans> 
    <!-- MySQL --> 
    <bean id="dataSource" 
       class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
       <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
       <property name="url" value="jdbc:mysql://localhost:3306/springdemo" /> 
       <property name="username" value="root" /> 
       <property name="password" value="frank1234" /> 
   </bean> 


    <bean id="transactionDAO" class="org.frank1234.spring.transaction.TransactionDAOImpl"> 
        <property name="dataSource" ref="dataSource" /> 
    </bean> 
    
</beans> 


测试类: 
public class TransactionMain { 
    public static void main(String[] args) throws Exception{ 
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
        TransactionDAO personService = (TransactionDAO) ctx.getBean("transactionDAO"); 

        Person person = new Person(); 
        person.setName("frank1234"); 
        person.setAge(21); 
        person.setSex("男"); 
        // 保存一条记录 


        Order order= new Order(); 
        order.setCost(10); 
        order.setCustomerId(12); 

        personService.savePersonAndOrder(person,order); 


    } 



执行后,数据库记录截图: 

 

可见person表的记录还是写入了。 


修改Spring配置文件如下: 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> 
<beans> 
    <!-- MySQL --> 
    <bean id="dataSource" 
       class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
       <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
       <property name="url" value="jdbc:mysql://localhost:3306/springdemo" /> 
       <property name="username" value="root" /> 
       <property name="password" value="frank1234" /> 
   </bean> 


    <bean id="transactionDAOTarget" class="org.frank1234.spring.transaction.TransactionDAOImpl"> 
        <property name="dataSource" ref="dataSource" /> 
    </bean> 
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property> 
    </bean> 
    <bean id="transactionDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
        <property name="proxyInterfaces"> 
            <list> 
                <value>org.frank1234.spring.transaction.TransactionDAO</value> 
            </list> 
        </property> 
        <property name="target"> 
            <ref bean="transactionDAOTarget"/> 
        </property> 
        <property name="transactionManager"> 
            <ref bean="transactionManager"/> 
        </property> 
        <property name="transactionAttributeSource"> 
            <ref bean="transactionAttributeSource"/> 
        </property> 
    </bean> 
    <bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource"> 

    </bean> 
</beans> 



清空数据库表记录,重新执行TransactionMain测试类。 
数据库记录截图: 

 

可见person没有写入,写入person和写入order是同一个事务了。 

这就是Spring声明式事务,其本质是AOP,将事务相关的代码作为切面织入了目标对象的方法中。 

4 JTA事务 
JTA可以解决跨多个数据源的事务问题,但是性能较差,使用的话要慎重,可以考虑采用补偿机制等来解决,例如先执行a(), 接着执行b() ,如果a()执行成功,b()执行失败,那么再执行一下c(),c()是a()的反操作。 
代码示例: 
public class JTATransactionMain { 
    public static void main(String[] args) throws Exception{ 
        UserTransaction tx = null; 
        try{ 
            Properties props = new Properties(); 
            props.put(Context.INITIAL_CONTEXT_FACTORY, jndi_factory);// weblogic.jndi.WLInitialContextFactory 
            props.put(Context.PROVIDER_URL, jndi_url);// t3://localhost:7001 
            Context ctx = new InitialContext(props); 
            tx=  (UserTransaction)ctx.lookup("transaction_url"); 
            //事务开始 
            tx.begin(); 
            //执行。。。 
            
            //事务提交 
            tx.commit(); 
        }catch (Exception e){ 
            e.printStackTrace(); 
            tx.rollback(); 
        } 
    } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值