2017-08-18 51 views
-1

我有一個春天啓動的Java應用程序卡夫卡連續流數據和應用業務邏輯後保存到數據庫中卡桑德拉春天啓動的應用程序線程安全

下面是僞類和函數,它們完全類似於我的應用程序。

KafkaStreamer

@Configuration 
@EnableKafka 
public class KafkaStreamer { 

    private static final Logger LOGGER = LoggerFactory.getLogger(MyDomain.class); 

    @Autowired 
    private MyController myController; 

    @KafkaListener(topics = "${my-topic}", group = "${my-group}") 
    public void streamFromKafka(String payload) { 
     myController.processPayload(payload); 
     LOGGER.info("I am continously streaming data from Kafka " 
       + "and forwarding it to controller for further processing...!"); 
    } 
} 

myController的

@Controller 
public class MyController { 

    private static final Logger LOGGER = LoggerFactory.getLogger(MyDomain.class); 

    @Autowired 
    private MyService myService; 

    public void processPayload(String payload) { 
     myService.applyBusinessLogic(payload); 
     LOGGER.info("Send to service for business-logic processing"); 
    } 
} 

爲MyService

@Service 
public class MyService { 
    private static final Logger LOGGER = LoggerFactory.getLogger(MyDomain.class); 

    @Autowired 
    private MyDomain myDomain; 

    public void applyBusinessLogic(String payload) { 
     myDomain.saveToDatabase(payload); 
     LOGGER.info("Applied business-logic"); 
    } 
} 

MYDOMAIN

@Repository 
    public class MyDomain { 

     private static final Logger LOGGER = LoggerFactory.getLogger(MyDomain.class); 

    @Autowired 
    private CassandraOperations cassandraTemplate; 

    /** The session. */ 
    private Session session = null; 

     public void saveToDatabase(String payload) { 
      saveToTableA(payload); 
      saveToTableB(payload); 
      // Hello, I have saved data to database 
      LOGGER.info("Saved data to database"); 
     } 

     private void saveToTableB(String payload) { 
      if (session == null) 
        session = cassandraTemplate.getSession(); 
      session.execute(payload); 
     } 

     private void saveToTableA(String payload) { 
      if (session == null) 
        session = cassandraTemplate.getSession() 
      session.execute(payload); 

     } 

    } 

上述僞代碼完全類似於我的原始應用程序。

正如你可以看到我做沒有任何類級別的變量比記錄儀等,在MYDOMAIN類

一些自動有線變量和卡桑德拉會話據我瞭解,自動線通過在spring-boot中的默認值是singleton

我將有效載荷(這是我的消息從卡夫卡)從一個類傳遞到另一個類的函數參數,而不是設置爲其他類的類級屬性。

我的問題是,

是我上面的應用程序體系結構或代碼線程安全的?

可以自動裝配創建問題,因爲默認情況下,它給出了一個類的單參考(點這裏要注意的是,我沒有比記錄儀和自動線變量其他任何類級別的變量)

如果你覺得如果有更好的方法或任何東西,請隨時寫。

非常感謝我。

+0

春季引導與單身無關。然而,Spring的默認行爲是單例,但是您可以使用註釋來定義自己的類的行爲方式。 –

+0

你會建議,根據我的上述情況,我應該使用'單身人士或原型' –

+0

單身人士不使用類變量通常是線程安全的(一些對象依賴性:您調用的方法中的所有對象都必須是線程安全的)。因此,我會首先嚐試使用單例代碼,查看特定部分並避免使用原型。 –

回答

0

如果您開始改變共享對象的狀態,則您的解決方案停止爲線程安全。

例如,如果你不得不在MyDomain單的Spring bean一個​​財產,並在saveToDatabase將其值設置和稍後(甚至在同一法)諮詢一下吧,這將是突變和你的代碼獲得了」線程安全。

例如:

@Repository 
public class MyDomain { 

    private String payload; 

    public void saveToDatabase(String payload) { 
     this.payload = payload; 
     saveToTableA(); 
     saveToTableB(); 
    } 


    private void saveToTableA() { 
     tableA.save(this.payload); 
    } 

在這種情況下,當多個線程調用您saveToDatabase同時使用不同的值,也不能保證什麼價值,你真的會保存到數據庫中saveToTableA()

相關問題