【问题标题】:Spring Propagation requires_new not workingSpring Propagation requires_new 不起作用
【发布时间】:2017-06-17 03:36:22
【问题描述】:

我有以下场景,我有 2 个服务层负责将数据插入到 emp 表和 dept 表中。

我已经编写了查询以在 dept 表上插入失败,即 deptno 不能接受长度 > 2 的 deptno,因此由于违反 DataIntegrity,它不会插入到 db 中。我不希望我之前的交易依赖于这个交易。所以使用了 REQUIRES_NEW 传播级别。

这是我的代码。

@Component
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private DeptService deptService;

    @Transactional(propagation = Propagation.REQUIRED)
    public boolean createEmployee() {
        employeeDao.insertEmployee();
        deptService.createDept();
        return false;
    }
}

@Component
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptDao deptDao;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public boolean createDept() {
        deptDao.insertDepartment();
        return false;
    }
}

下面是道层

@Component
public class EmployeeDaoImpl implements EmployeeDao {

    private String empInsert = "INSERT INTO emp VALUES ('1000','Ravi','CLERK','7782','1990-01-01','1235.00',NULL,'50');";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public boolean insertEmployee() {

        int n = jdbcTemplate.update(empInsert);
        return true;
    }
}

@Component
public class DeptDaoImpl implements DeptDao {

    private String deptInsert = "INSERT INTO dept VALUES ('500','MATERIAL','ALASKA');";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public boolean insertDepartment(){
        jdbcTemplate.update(deptInsert);
        return true;
    }

}

下面的代码是从主类调用的

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("txrequirednew.xml");
        EmployeeService es = (EmployeeService) context.getBean("employeeServiceImpl");
        es.createEmployee();
    }

以下是我的应用程序上下文:

   <beans>

     <context:annotation-config/>
        <context:component-scan base-package="txrequirednew">
    </context:component-scan>

        <bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/tejadb"></property>
            <property name="username" value="root"/>
            <property name="password" value="sai"/>
        </bean>

        <!-- Dao Configurations-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>

        <tx:annotation-driven transaction-manager="transactionManager" />

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

    </beans>

当我尝试执行时,两个事务都回滚。但我不希望我的第一笔交易被回滚。

我在这里遗漏了什么,导致两个事务都回滚? 我该如何解决这个问题。

【问题讨论】:

    标签: spring spring-transactions


    【解决方案1】:

    如果内部事务通过 requires_new 传播回滚,则事务范围是正确的,它不应该影响外部事务,因为

    PROPAGATION_REQUIRES_NEW 为给定范围启动一个新的、独立的“内部”事务。该事务将完全独立于外部事务提交或回滚,具有自己的隔离范围,自己的一组锁等。外部事务将在内部事务开始时暂停,并在内部事务完成后恢复完全的。 ...

    但是你应该处理你的内部方法抛出的异常,如果你没有处理它们,它将回滚外部事务。 Spring 框架事务只会回滚 RunTimeException 而不会回滚其他检查过的异常,如 SqlException。

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      相关资源
      最近更新 更多