简体   繁体   English

通过连接到多个数据库进行Spring事务

[英]Spring transaction by connecting to multiple databases

I am trying to work on a small program where I can connect to multiple databases using Spring and trying to use Spring transactions by deploying my web-application on weblogic server. 我正在尝试一个小程序,在这里我可以使用Spring连接到多个数据库,并通过在Weblogic服务器上部署Web应用程序来尝试使用Spring事务。 The problem is that the transaction management is not working properly. 问题是事务管理无法正常工作。 I am trying to insert records in 2 databases, the first one inserts without throwing any exceptions, where as the second insert query is written such that it throws an exception. 我正在尝试在2个数据库中插入记录,第一个插入时不引发任何异常,在编写第二个插入查询时,它引发了异常。 Ideally in this situation the transaction should rollback but the first transaction is committed without any issues. 理想情况下,事务应回滚,但第一个事务已提交而没有任何问题。

Here is my spring-config.xml file 这是我的spring-config.xml文件

<context:component-scan base-package="com.examples" />

<!-- Database1 -->

<bean id="db1DataSource" 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/mydb1" />
    <property name="username" value="root" />
    <property name="password" value="" />
</bean>

<!-- Database2 -->

<bean id="db2DataSource" 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/mydb2" />
    <property name="username" value="root" />
    <property name="password" value="" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix">
        <value>/WEB-INF/views/</value>
    </property>
    <property name="suffix" value=".jsp" />
</bean>

This is my controller: 这是我的控制器:

@Controller
public class EmployeeController {

    @Autowired
    private CommonEmployeeService commonService;

    @RequestMapping(value = "/employee", method = GET)
    public String showPersonListForGivenAge(
            @RequestParam(value = "id") int id,
            @RequestParam(value = "name") String name,
            @RequestParam(value = "email") String email,
            Map<String, Object> model) {

        Employee e = new Employee(id,name);
        EmployeeDetails details = new EmployeeDetails(id,email);

        commonService.insert(e, details);

        return "welcome";
    }
}

This is my common service: 这是我的共同服务:

@Service
public class CommonEmployeeService {

    @Autowired
    EmployeeDetailsService detailsService;

    @Autowired
    EmployeeService service;


    @Transactional
    public boolean insert(Employee e, EmployeeDetails details) {
        service.insert(e);
        detailsService.insert(details);
        return true;
    }
}

These are my other services: 这些是我的其他服务:

EmployeeService.java EmployeeService.java

@Service

public class EmployeeService {

    @Autowired
    EmployeeDao dao;

    //@Transactional(propagation=Propagation.REQUIRED)
    public boolean insert(Employee e) {
        return dao.insert(e);
    }
}

EmployeeDetailsService.java -- The DAO in this service throws NullPointerException EmployeeDetailsS​​ervice.java-此服务中的DAO抛出NullPointerException

@Service
public class EmployeeDetailsService {

    @Autowired
    EmployeeDetailsDao dao;

    //@Transactional(propagation=Propagation.REQUIRED)
    public boolean insert(EmployeeDetails e) {
        return dao.insert(e);
    }

}

Update: Adding Dao Classes: 更新:添加道类:

EmployeeDao.java: EmployeeDao.java:

@Repository
public class EmployeeDao {

    JdbcTemplate template;

    @Resource(name = "db1DataSource")
    public void setDataSource(DataSource dataSource) {
        this.template = new JdbcTemplate(dataSource);
    }

    public boolean insert(Employee e) {
        int cnt = template.update("insert into Employee values(?,?)",
                e.getId(), e.getName());
        if (cnt > 0) {
            return true;
        }
        return false;
    }
}

EmployeeDetailsDao.java EmployeeDetailsDao.java

@Repository
public class EmployeeDetailsDao {

    JdbcTemplate template;

    @Resource(name = "db2DataSource")
    public void setDataSource(DataSource dataSource) {
        this.template = new JdbcTemplate(dataSource);
    }

    public boolean insert(EmployeeDetails e) {
        if(e != null){
            throw new NullPointerException();   
        }

        int cnt = template.update("insert into EmployeeDetails values(?,?)",
                e.getId(), e.getEmail());
        if (cnt > 0) {
            return true;
        }
        return false;
    }
}

Try adding below in spring-config.xml : 尝试在spring-config.xml添加以下内容:

<context:component-scan base-package=“your.packagename.contatining.EmployeeDetailsDao” />
<mvc:annotation-driven />

and changing @Transactional in your CommonEmployeeService with @Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED) as below 并使用@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)CommonEmployeeService更改@Transactional ,如下所示

@Service
public class CommonEmployeeService {

    @Autowired
    EmployeeDetailsService detailsService;

    @Autowired
    EmployeeService service;

@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
    public boolean insert(Employee e, EmployeeDetails details) {
        service.insert(e);
        detailsService.insert(details);
        return true;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM