Spring学习04

Sprint之事务

这篇文章蛮详细的https://www.cnblogs.com/yixianyixian/p/8372832.html

事务的7大传播行为

事务中可能出现的3种问题

事务的隔离级别

一,使用jdbc模板操作数据库,封装了数据库的连接,资源释放,没有开启事务

0,导包spring-tx包

1,User实体类,UserDao接口(增删查改方法)

实现类UserDaoImp(私有字段private JdbcTemplate jt;通过set注入)

实现类方法(通过JdbcTemplate操作数据库):

a,增

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao {

    @Autowired
    private JdbcTemplate JdbcTemplate;

    @Override
    public int findBookPriceByIsbn(String isbn) {
        String sql = "SELECT price FROM book WHERE isbn = ?";

        return JdbcTemplate.queryForObject(sql, Integer.class, isbn);
    }
}

 

b,根据id查找

@Override
    public User getById(Integer id) {
        String sql = "select * from user where uid=?";
        return jt.queryForObject(sql, new RowMapper<User>() {

            @Override
            public User mapRow(ResultSet rs, int arg1) throws SQLException {
                User u = new User();
                u.setId(rs.getInt("uid"));
                u.setName(rs.getString("uname"));
                u.setPassword(rs.getString("upassword"));
                u.setSex(rs.getString("sex"));
                u.setBirthday(rs.getString("birthday"));
                return u;
            }

        }, id);
    }


c,查找全部User

@Override
    public List<User> getAll() {
        String sql = "select * from user";
        List<User> list = jt.query(sql, new RowMapper<User>() {

            @Override
            public User mapRow(ResultSet rs, int arg1) throws SQLException {
                User u = new User();
                u.setId(rs.getInt("uid"));
                u.setName(rs.getString("uname"));
                u.setPassword(rs.getString("upassword"));
                u.setSex(rs.getString("sex"));
                u.setBirthday(rs.getString("birthday"));
                return u;
            }
        });
        return list;
    }

2,xml文件配置

导入连接池配置

<context:property-placeholder location="classpath:db.properties"/>

连接池放入容器

<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

连接池注入jdbcTemplate,注意property的name不要写错,可以去翻源码

<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>

jdbcTemplate注入Dao

<bean name="userDao" class="com.cl.jdbcTemplate.UserDaoImp">
<property name="jt" ref="jdbcTemplate"></property>
</bean>

3,测试类

完全手动方法:啥也不需要,一个类一个方法即可。

@Test
    public void fun1() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql:///mybase");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        // 创建jdbc模板对象
        JdbcTemplate jt = new JdbcTemplate();
        jt.setDataSource(dataSource);
        String sql = "insert into user values('110','hehe','123456','male','1999-09-09')";
        jt.update(sql);
    }

注入了模板的Dao的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Resource(name = "userDao")
    private UserDao ud;
    @Test
    public void fun() {
        User u = new User();
        u.setBirthday("1998-09-09");
        u.setName("lily");
        u.setPassword("mypassword");
        u.setSex("female");
        ud.save(u);
    }
    }

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

PlateformTransactionManager,事务核心管理器,封装事务操作,依赖连接池

如果Dao的实现类继承JdbcDaoSupport可以直接调用getJdbcTemplate方法获得JdbcTemplate处理sql语句。

二,使用显示事务模板+注解,或者不显示使用模板,配置需要事务的方法

Service的实现类,如

public class ServiceImp implements AccountService {
    private AccountDao ad;
    private TransactionTemplate tt;

    public void setTt(TransactionTemplate tt) {
        this.tt = tt;
    }

    public void setAd(AccountDao ad) {
        this.ad = ad;
    }
        @Override//下面使用注解配置事务通知,方便多了
    @Transactional(isolation=Isolation.REPEATABLE_READ,readOnly=false,propagation=Propagation.REQUIRED)
    public void transfer(Integer from, Integer to, Double money) {
        tt.execute(new TransactionCallbackWithoutResult() {

            @Override // 封装了try-catch和回滚操作
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                ad.minusMoney(from, money);
                ad.addMoney(to, money);
            }
        });
    }
}

 

xml配置文件中先配置DataSource,然后将DataSource注入transactionManager,

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

配置事务模板对象

<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>

使用注解配置事务通知,这里感觉注解方便许多

<tx:annotation-driven/>

连接池注入Dao

<bean name="accountDao" class="com.cl.springtx.AccountImp">
<property name="dataSource" ref="dataSource"></property>
</bean>

Dao和transactionTemplate注入Service

<bean name="accountService" class="com.cl.springtx.ServiceImp">
<property name="ad" ref="accountDao"></property>
<property name="tt" ref="transactionTemplate"></property>
</bean>

如果不用注解配置+注解方法(直接在需要开启事务通知的方法上使用注解),事务通知的配置如下,指定某个包的哪些方法需要开启事务通知

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- get和find设置为只读 -->
<tx:method name="get*" propagation="REQUIRED" isolation="REPEATABLE_READ" read-only="true"></tx:method>
<tx:method name="find*" propagation="REQUIRED" isolation="REPEATABLE_READ" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 织入 -->
<aop:config>
<aop:pointcut expression="execution(* com.cl.springtx.*ServiceImp.*(..))" id="account-tx"/>        
<aop:advisor advice-ref="txAdvice" pointcut-ref="account-tx"/><!-- 切面 -->
</aop:config> 

总之,jdbc模板封装了数据库的操作,而transaction模板又封装了jdbc的操作,使得try-catch和回滚操作不用手动处理。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值