Transaction
소개
이 문서는 Transaction 처리 방법에 대해 설명하고 있습니다.
Transaction 처리 방법
기본적으로 클래스의 public 메소드 위에 [Transaction]
을 사용하면 Transaction 처리가 가능합니다.
[Transaction]
public void Test(){
// 생략
}
Autowire된 객체에서 Transaction 처리 가능
Spring.NET이 생성한 인스턴스(Proxy 객체)에서만 Transaction 처리가 가능합니다. 그렇기 때문에 Autowire 된 객체에서 Transaction 처리가 가능합니다.
// Service
public class TransactionTestService : ITransactionTestService
{
[Autowire]
public ITransactionTestDao TransactionTestDao { get; set; }
[Transaction]
public void Do()
{
TransactionTestDao.Insert(1);
TransactionTestDao.Delete(2);
}
}
// Controller
public class TransactionController
{
[Autowire]
public ITransactionTestService TransactionTestService { get; set; }
// transaction 처리 불가
public ActionResult BadTest()
{
var transactionTestService = new TransactionTestService();
transactionTestService.Do();
}
// transaction 처리 가능
public ActionResult GoodTest()
{
TransactionTestService.Do();
}
}
호출하는 메소드에 Transaction Attribute 사용
Spring에 의해 랩핑된 메서드를 호출할 때만 Transaction 처리가 가능하므로 객체 내부 호출은 Transaction 처리가 안 됩니다. 실제 호출하는 메소드에 [Transaction]
을 사용해야 합니다.
// Controller
public class TransactionController
{
[Autowire]
public ITransactionTestService TransactionTestService { get; set; }
// transaction 처리 불가
public ActionResult BadTest()
{
TransactionTestService.Do1();
}
// transaction 처리 가능
public ActionResult GoodTest()
{
TransactionTestService.Do2();
}
}
// Service
// [Transaction] 위치 주의
public class TransactionTestService : ITransactionTestService
{
[Autowire]
public ITransactionTestDao TransactionTestDao { get; set; }
public void Do1()
{
DoDbProc1();
}
[Transaction]
public void DoDBProc1()
{
TransactionTestDao.Insert(1);
TransactionTestDao.Delete(2);
}
[Transaction]
public void Do2()
{
DoDbProc2();
}
public void DoDBProc2()
{
TransactionTestDao.Insert(1);
TransactionTestDao.Delete(2);
}
}
여러 DB에 Transaction 처리
Provider에 Transaction Manager DB별로 선업합니다. Attribute로 Manager 사용을 명시적으로 선언합니다.
<object id="transactionManager" type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
<property name="DbProvider" ref="DbProvider" />
</object>
<object id="transactionManagerJB" type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
<property name="DbProvider" ref="DbProvider_JangBoGo" />
</object>
<tx:attribute-driven transaction-manager="transactionManager"/>
<tx:attribute-driven transaction-manager="transactionManagerJB"/>
예시
public class TempTestService : ITempTestService
{
[Autowire]
public ICommonObjectDao COD { private get; set; }
[Autowire]
[AdoTemplateName("AdoTemplate_JangBoGo")]
public ICommonObjectDao CODJ { private get; set; }
[Autowire]
[AdoTemplateName("AdoTemplate_OrderMall")]
public ICommonObjectDao CODOM { private get; set; }
[Transaction]
public void Test()
{
COD.Query(new ExecuteQuery { Query = @"INSERT INTO TempTest(val) values (@val)", DbParam = new { val = Guid.NewGuid().ToString() } });
CODJ.Query(new ExecuteQuery { Query = @"INSERT INTO TempTest(val) values (@val)", DbParam = new { val = Guid.NewGuid().ToString() } });
CODOM.Query(new ExecuteQuery { Query = @"INSERT INTO TempTest(val) values (@val)", DbParam = new { val = Guid.NewGuid().ToString() } });
throw new Exception();
}
}
결과
select * from adprintNewDB.dbo.TempTest
select * from JangBoGo.dbo.TempTest
select * from ordermall.dbo.TempTest
Manager 설정을 안한 ordermall에만 데이터가 저장됩니다.
-----
empty
-----
empty
-----
1 | 6a923ac2-a325-4ffc-8efd-782b44c07cb9
-----