交易性更改集合中的记录

时间:2018-10-22 09:09:10

标签: java collections transactional

我有此代码:

import java.util.*;


class MyClass {
    public Boolean field;
}


public class Main {

    Map<String, MyClass> map = new HashMap<>();

    private void fillCollection() {

        MyClass record1 = new MyClass();
        MyClass record2 = new MyClass();
        MyClass record3 = new MyClass();

        record1.field = false;
        record2.field = false;
        record3.field = false;

        map.put("record1", record1);
        map.put("record2", record2);
        map.put("record3", record3);
    }

    private void changeObject(MyClass record) throws Exception {

        if (new Random().nextInt(2) == 0) {
            throw new Exception("Exception during Object change");
        }

        record.field = true;
    }

    private void changeCollection(List<String> recordKeys) {

        for (String key : recordKeys) {
            try {
                changeObject(map.get(key));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void printCollection() {

        for (String key : map.keySet()) {

            System.out.println(key + " " + map.get(key).field);
        }
    }

    public static void main(String[] args) throws Exception {

        Main application = new Main();

        new Thread(new Runnable() {
            @Override
            public void run() {
                application.fillCollection();
            }
        }).start();

        Thread.sleep(100);

        new Thread(new Runnable() {
            @Override
            public void run() {

                List<String> recordKeys = new ArrayList<>();
                recordKeys.add("record1");
                recordKeys.add("record2");

                application.changeCollection(recordKeys);
            }
        }).start();

        Thread.sleep(100);

        new Thread(new Runnable() {
            @Override
            public void run() {

                application.printCollection();
            }
        }).start();
    }
}

Еxplanation:

  • 有对象映射(键是字符串)。

  • 在一个线程中,此Map充满了对象。

  • 在其他线程中,应更改某些(不是全部)对象。在更改对象的过程中,可能会引发某些异常(在上述情况下,将在方法“ changeObject”中对其进行模拟)。如果出现异常,则不应将对象添加到地图。

这就是问题:在Map中添加所有对象应该是事务性的。也许我在这里不使用严格的词,所以我解释说:最后要么更改所有记录,要么都不更改。

所以问题是:能否实现? “ changeCollection”方法应如何显示?

当前,我使用以下解决方案:创建临时地图,用主地图中的记录克隆填充它,尝试更改此临时地图中的克隆记录,并且在没有异常的情况下,我使主地图变量指向临时地图对象。我不喜欢这种解决方案,更喜欢没有克隆的解决方案。

另一件事:我不需要任何外部库。

1 个答案:

答案 0 :(得分:0)

是的,可以实现。请查看下面的代码段。

<html>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<body>
  <div id="container">
    <div id="header">
      <h1>Citation Generator</h1>
      <h3>it's totally amazing</h3>
    </div>
    <div class="contentContainer">
	    <div class="col-md-6 col-sm-6">
	      <div id="citationList">
	        <h4>Your Citations</h4>
	        <ul id="citations">
	          Looks like you don't have any citations made yet!
	        </ul>
	      </div>
	    </div>
	    <div class="col-md-6 col-sm-6">
	      <div id="creationForm">
	        <h4>Create a Citation</h4>
	        <form>
	          <!-- Author -->
	          <div class="row">
		          <label for="authorFirst">Author's first name:</label>
		          <input id="authorFirst" type="text" class="textBox" />
	          </div>
	          <div class="row">
		          <label for="authorLast">Author's last name:</label>
		          <input id="authorLast" type="text" class="textBox" />
	          </div>
	          <br />
	          <!-- Website -->
	          <div class="row">
		          <label for="pageTitle">Title of page/article:</label>
		          <input id="pageTitle" type="text" class="textBox" />
		      </div>
	          <div class="row">
		          <label for="siteTitle">Title of website:</label>
		          <input id="siteTitle" type="text" class="textBox" />
		      </div>
	          <br />
	          <!-- Dates -->
	          <div class="row">
		          <label for="datePublished">Date published:</label>
		          <input id="datePublished" type="text" class="textBox" />
		      </div>
	          <div class="row">
		          <label for="dateAccessed">Date accessed:</label>
		          <input id="dateAccessed" type="text" class="textBox" />
		      </div>
	        </form>
	      </div>
	      <div id="adSpace">
	        <img src="https://via.placeholder.com/300x300.jpg?text=Placeholder+Advertisment" />
	        <p>Advertisment</p>
	      </div>
	    </div>
    </div>
  </div>
</body>

</html>