1 package com.atlassian.sal.spring.connection;
2
3 import com.atlassian.fugue.Option;
4 import com.atlassian.sal.api.rdbms.ConnectionCallback;
5 import com.atlassian.sal.spi.HostConnectionAccessor;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.transaction.PlatformTransactionManager;
9 import org.springframework.transaction.TransactionDefinition;
10 import org.springframework.transaction.TransactionStatus;
11 import org.springframework.transaction.support.DefaultTransactionDefinition;
12 import org.springframework.transaction.support.TransactionCallback;
13 import org.springframework.transaction.support.TransactionTemplate;
14
15 import javax.annotation.Nonnull;
16 import java.sql.Connection;
17 import java.sql.SQLException;
18
19
20
21
22
23
24
25
26
27
28 public class SpringHostConnectionAccessor implements HostConnectionAccessor {
29 private static final Logger log = LoggerFactory.getLogger(SpringHostConnectionAccessor.class);
30
31 private final ConnectionProvider connectionProvider;
32
33 private final PlatformTransactionManager transactionManager;
34
35 public SpringHostConnectionAccessor(@Nonnull final ConnectionProvider connectionProvider, @Nonnull final PlatformTransactionManager transactionManager) {
36 this.connectionProvider = connectionProvider;
37 this.transactionManager = transactionManager;
38 }
39
40 @Override
41 public <A> A execute(final boolean readOnly, final boolean newTransaction, @Nonnull final ConnectionCallback<A> callback) {
42
43 final DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
44 transactionDefinition.setName("SALSpringTx");
45 transactionDefinition.setReadOnly(readOnly);
46 transactionDefinition.setPropagationBehavior(newTransaction ? TransactionDefinition.PROPAGATION_REQUIRES_NEW : TransactionDefinition.PROPAGATION_REQUIRED);
47
48
49 final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, transactionDefinition);
50
51
52
53 return (A) transactionTemplate.execute(new TransactionCallback() {
54 @Override
55 public Object doInTransaction(final TransactionStatus status) {
56
57
58 final Connection connection = connectionProvider.getConnection();
59
60
61 return callback.execute(connection);
62 }
63 });
64 }
65
66 @Nonnull
67 @Override
68 public Option<String> getSchemaName() {
69 return connectionProvider.getSchemaName();
70 }
71
72
73
74
75 public interface ConnectionProvider {
76
77
78
79
80
81
82
83
84
85
86 @Nonnull
87 Connection getConnection();
88
89
90
91
92
93
94
95
96 @Nonnull
97 Option<String> getSchemaName();
98 }
99 }