Programmatic transaction management در Spring

Spring روش هاي مختلفي براي Transaction Management ارائه مي‌دهد که بطور کلي در دو دسته Declarative و Programmatic قرار مي‌گيرند. پيشنهاد خود Spring استفاده از Declarative Transaction Management است. زيرا استفاده از اين روش ساده‌تر است و انعطاف پذيري بيشتري دارد. در اين روش همه تنظيمات مربوطه در XML Config ها انجام مي‌گردد.

با اين حال گاهي لازم است کنترل هاي بيشتري در اختيار برنامه ساز قرار گيرد يا تغييراتي توسط او در مکانيزم‌هاي پيش فرض Spring جهت Transaction Management صورت گيرد. در اين موارد مي‌توان از Programmatic Transaction Management استفاده کرد.

در روش Programmatic برنامه ساز مستقيما با کلاسها درگير است و عمليات Commit و Rollback از طريق خود برنامه انجام مي‌شود. در اين نوشته نمونه‌اي از اين روش با استفاده از Transaction Manager ارائه شده است.

مساله:
مي‌خواهيم دو تراکنش پايگاه داده (مثلا insert در دو جدول جداگانه) را بصورت Transactional پياده سازي نماييم:

تکنولوژي هاي بکار رفته:
JDK1.6
spring-framework-3.0.5


پياده سازي کلاس MyDAO
ابتدا کلاس MyDAO که پياده سازي تراکنش هاي مربوطه در آنها انجام شده است:

package tx.programmatic.txmanagerstyle;

import java.sql.*;

public class MyDAO {

   private Connection conn = null;

   public MyDAO(Connection conn){
      this.conn = conn;
   }

   public void insertIntoTable1(int p1, String p2) throws SQLException{
      String qry = “insert into myTestTable1 (col1,col2) values (“+p1+”,’”+p2+”‘)” ;
      Statement stat = conn.createStatement();
      stat.execute(qry);
   }

   public void insertIntoTable2(int p1, String p2) throws SQLException{
      String qry = “insert into myTestTable2 (col1,col2) values (“+p1+”,’”+p2+”‘)” ;
      Statement stat = conn.createStatement();
      stat.execute(qry);
   }
}

پياده سازي کلاس Service

package tx.programmatic.txmanagerstyle;

import java.sql.Connection;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.apache.commons.dbcp.BasicDataSource;

public class myService {

   private DataSource createTransactionDataSource() throws ClassNotFoundException{
      Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);

      DataSource ds = new BasicDataSource();
      ((BasicDataSource)ds).setUrl(“jdbc:microsoft:sqlserver://dbserver:1433;databaseName=myDB;SelectMethod=Cursor”);
      ((BasicDataSource)ds).setUsername(“sa”);
      ((BasicDataSource)ds).setPassword(“password”);
      ((BasicDataSource)ds).setDriverClassName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);
      return ds;
   }

   private DataSourceTransactionManager getTransactionManager(){
      DataSourceTransactionManager obj = null;
      try {
         obj = new DataSourceTransactionManager(createTransactionDataSource());
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }

      return obj;
   }

   public void doService(){
      DefaultTransactionDefinition def = new DefaultTransactionDefinition();
      /* explicitly setting the transaction name is something that can only be done programmatically */
      def.setName(“TestTX”);
      def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

      DataSourceTransactionManager txManager = getTransactionManager();
      TransactionStatus status = txManager.getTransaction(def);

      try {
         MyDAO dao;

         Connection conn =
            DataSourceUtils.getConnection(txManager.getDataSource());

         dao = new MyDAO(conn);

         // First Transaction:
         dao.insertIntoTable1(1,”testName”);

         // Second Transaction:
         dao.insertIntoTable2(1,”testDesc”);

         txManager.commit(status);

      } catch (Exception ex) {
         txManager.rollback(status);
      }
   }
}

متد createTransactionDataSource يک نمونه DataSource براي اتصال به پايگاه داده ايجاد مي‌کند. توجه شود که براي Transaction Management حتما SelectMethod بايد برابر با Cursor باشد.

متد getTransactionManager يک نمونه از کلاس DataSourceTransactionManager را ايجاد مي‌کند.

در متد doService عمليات اصلي پياده مي‌شود. در ابتداي آن DataSourceTransactionManager ساخته مي‌شود و وضعيت جاري در status ذخيره مي‌شود. سپس در يک Try Catch عمليات اصلي که درج در دو جدول پايگاه داده است پياده سازي مي‌گردد. در صورتي که هيچ خطايي رخ ندهد تراکنش Commit و در غير اين صورت Rollback مي‌گردد.

با اجراي متد doService ، عمل درج در دو جدول مورد نظر بصورت Transactional انجام مي‌شود.

نکته بسيار مهم:
همانگونه که در مثال بالا پيدا است، در صورت نياز به استفاده از Connection پايگاه داده بايد آن را از متد getConnection موجود در کلاس org.springframework.jdbc.datasource.DataSourceUtils دريافت نمود.

استفاده از Spring Dependency Injection در مثال بالا:
مي‌توان مثال بالا را يک قدم ارتقا داد. بدين صورت که تعريف DataSource و TransactionManager را در يک XML قرار داد و آن را به برنامه inject نمود.

محتواي فايل کانفيگ DataSourceTXManagement.xml:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
      xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
      xmlns:aop=”http://www.springframework.org/schema/aop”
      xmlns:tx=”http://www.springframework.org/schema/tx”
      xsi:schemaLocation=”
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd”>

   <bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”>
      <property name=”driverClassName” value=”com.microsoft.jdbc.sqlserver.SQLServerDriver”/>
      <property name=”url” value=”jdbc:microsoft:sqlserver://dbserver:1433;databaseName=myDB”/>
      <property name=”username” value=”sa”/>
      <property name=”password” value=”password”/>
   </bean>

   <bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
      <property name=”dataSource” ref=”dataSource”/>
   </bean>
</beans>

حال متد getTransactionManager را بدين صورت تغيير مي‌دهيم:

private DataSourceTransactionManager getTransactionManager(){
   ApplicationContext context = new ClassPathXmlApplicationContext(“DataSourceTXManagement.xml”);
   DataSourceTransactionManager obj = (DataSourceTransactionManager) context.getBean(“txManager”);
   return obj;
}

با برچسب: ,
پست شده در Spring

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*


× 1 = چهار

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

تماس با من: admin@paspars.com